<template>
  <div class="free-running">
    <!-- 返回按钮 -->
    <div class="back-button" @click="goBack">
      <svg t="1686036128495" viewBox="0 0 1024 1024" width="24" height="24">
        <path d="M671.968 912c-12.288 0-24.576-4.672-33.952-14.048L286.048 545.984c-18.752-18.72-18.752-49.12 0-67.872l351.968-352c18.752-18.752 49.12-18.752 67.872 0 18.752 18.72 18.752 49.12 0 67.872L387.872 512l318.016 318.016c18.752 18.752 18.752 49.12 0 67.872C696.544 907.328 684.256 912 671.968 912z" fill="#ffffff"></path>
      </svg>
      <span>返回</span>
    </div>
    
    <!-- 网络状态指示器 -->
    <div class="network-status" v-if="!isOnline && isRunning">
      <svg viewBox="0 0 24 24" width="18" height="18">
        <path d="M19.35,10.04C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.04C2.34,8.36 0,10.91 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.04M19,18H6A4,4 0 0,1 2,14C2,11.81 3.55,10 5.78,10H6.71C7.37,7.69 9.5,6 12,6A5.5,5.5 0 0,1 17.5,11.5V12H19A3,3 0 0,1 22,15A3,3 0 0,1 19,18M7.04,15L5.63,16.41L9.05,19.81L5.63,23.22L7.04,24.63L12.06,19.61L7.04,14.61V15M12.05,8.18L7.04,13.19L12.05,18.2L17.06,13.19L12.05,8.18Z" fill="#f44336"/>
      </svg>
      <span>离线模式</span>
    </div>
    
    <!-- 重新选择目的地按钮 -->
    <div v-if="isTargetRunMode && !isRunning && !showDestinationPanel && targetRoute" class="reselect-button" @click="showDestinationPanel = true">
      <svg viewBox="0 0 24 24" width="20" height="20">
        <path d="M19,8L15,12H18A6,6 0 0,1 12,18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20A8,8 0 0,0 20,12H23L19,8M6,12A6,6 0 0,1 12,6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4A8,8 0 0,0 4,12H1L5,16L9,12H6Z" fill="#ffffff"/>
      </svg>
      <span>重选目的地</span>
    </div>
    
    <!-- 跑步模式切换 -->
    <div class="run-mode-selector" v-if="!isRunning">
      <button :class="{'active': !isTargetRunMode}" @click="switchToFreeRun">自由跑</button>
      <button :class="{'active': isTargetRunMode}" @click="switchToTargetRun">目标跑</button>
    </div>
    
    <!-- 地图容器 -->
    <div ref="mapContainer" class="map-container"></div>
    
    <!-- 目的地选择面板 -->
    <div v-if="isTargetRunMode && !isRunning && showDestinationPanel" class="destination-panel">
      <div class="panel-title">设置目标路线</div>
      <div class="search-container">
        <div class="search-icon">
          <svg viewBox="0 0 1024 1024" width="20" height="20">
            <path d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6c3.2 3.2 8.4 3.2 11.6 0l43.6-43.5c3.2-3.2 3.2-8.4 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z" fill="#999"></path>
          </svg>
        </div>
        <input 
          type="text" 
          v-model="searchKeyword" 
          placeholder="搜索目的地..." 
          @keyup.enter="searchDestination"
        />
        <button @click="searchDestination" class="search-btn">搜索</button>
      </div>
      
      <div class="destination-list">
        <div v-for="poi in nearbyPOIs" :key="poi.id" class="destination-item" @click="selectDestination(poi)">
          <div class="poi-info">
            <div class="poi-name">{{poi.name}}</div>
            <div class="poi-distance">距离您 {{poi.distance}}</div>
          </div>
          <div class="select-btn">选择</div>
        </div>
      </div>
    </div>
    
    <!-- 底部迷你音乐播放器，只在运行时显示 -->
    <div class="mini-music-player" v-if="isRunning && !isPanelExpanded">
      <div class="album-cover">
        <img :src="currentSong.cover" alt="album cover">
      </div>
      <div class="music-info">
        <div class="song-title">{{ currentSong.title }}</div>
        <div class="artist-name">{{ currentSong.artist }}</div>
      </div>
      <div class="player-controls">
        <svg viewBox="0 0 1024 1024" width="24" height="24" @click="togglePlay">
          <path v-if="!isPlaying" d="M512 128a384 384 0 1 1 0 768 384 384 0 0 1 0-768z m0 85.333333a298.666667 298.666667 0 1 0 0 597.333334 298.666667 298.666667 0 0 0 0-597.333334z m-106.666667 149.333334l256 149.333333-256 149.333333V362.666667z" fill="#ffffff"></path>
          <path v-else d="M512 128a384 384 0 1 1 0 768 384 384 0 0 1 0-768z m0 85.333333a298.666667 298.666667 0 1 0 0 597.333334 298.666667 298.666667 0 0 0 0-597.333334z m106.666667 149.333334v213.333333h-213.333334V362.666667h213.333334z" fill="#ffffff"></path>
        </svg>
      </div>
    </div>

    <!-- 状态指示器 -->
    <div class="status-indicators" v-if="isRunning">
      <!-- GPS信号强度指示器 -->
      <div class="status-indicator" :class="gpsSignalStatus">
        <svg viewBox="0 0 24 24" width="18" height="18">
          <path v-if="gpsSignalStatus === 'strong'" d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6M12,8A4,4 0 0,0 8,12A4,4 0 0,0 12,16A4,4 0 0,0 16,12A4,4 0 0,0 12,8Z" fill="#4CAF50"/>
          <path v-if="gpsSignalStatus === 'weak'" d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6M12,8A4,4 0 0,0 8,12A4,4 0 0,0 12,16A4,4 0 0,0 16,12A4,4 0 0,0 12,8Z" fill="#FFC107"/>
          <path v-if="gpsSignalStatus === 'lost'" d="M1,21H3V9H1V21M5,21H7V3H5V21M9,21H11V12H9V21M13,21H15V8H13V21M17,21H19V14H17V21Z" fill="#F44336"/>
        </svg>
        <span>{{ gpsStatusText }}</span>
      </div>
      
      <!-- 自动暂停指示器 -->
      <div class="status-indicator" v-if="isAutoPaused">
        <svg viewBox="0 0 24 24" width="18" height="18">
          <path d="M14,19H18V5H14M6,19H10V5H6V19Z" fill="#ffffff"/>
        </svg>
        <span>已暂停</span>
      </div>
    </div>
    
    <!-- Toast提示框 -->
    <transition name="fade">
      <div class="toast-message" v-if="showingToast">
        {{ toastMessage }}
      </div>
    </transition>

    <!-- 全屏扩展面板 -->
    <div class="sliding-panel" :class="{ 'expanded': isPanelExpanded }">
      <!-- 面板顶部拖动区域 -->
      <div 
        class="panel-header"
        @touchstart="startDrag"
        @touchmove="onDrag" 
        @touchend="endDrag"
      >
        <div class="handle-bar"></div>
        
        <!-- 运动类型标题 -->
        <div class="workout-title" v-if="isPanelExpanded">
          <svg viewBox="0 0 1024 1024" width="20" height="20">
            <path d="M615.2 123.8c-19.2 0-32-12.8-32-32V64c0-19.2 12.8-32 32-32s32 12.8 32 32v32c0 12.8-12.8 27.8-32 27.8zM410.6 123.8c-19.2 0-32-12.8-32-32V64c0-19.2 12.8-32 32-32s32 12.8 32 32v32c0 12.8-16 27.8-32 27.8zM816 195.8H208c-38.4 0-70.4 32-70.4 70.4v76.8h748.8v-76.8c0-38.4-32-70.4-70.4-70.4zM137.6 780.6c0 38.4 32 70.4 70.4 70.4h608c38.4 0 70.4-32 70.4-70.4V374.4H137.6v406.2z" fill="#333" />
          </svg>
          <span>户外跑步</span>
        </div>
      </div>
      
      <!-- 收起状态数据显示 -->
      <div class="mini-stats" v-if="!isPanelExpanded">
        <div class="big-stat">
          <div class="big-stat-value">{{ (distance / 1000).toFixed(2) }}</div>
          <div class="big-stat-unit">km</div>
          <div class="big-stat-label">运动距离</div>
        </div>
        
        <div class="mini-stats-grid">
          <div class="mini-stat-box">
            <div class="mini-stat-value">{{ formatTime(duration) }}</div>
            <div class="mini-stat-label">运动时间</div>
          </div>
          <div class="mini-stat-box">
            <div class="mini-stat-value">{{ paceFormatted }}</div>
            <div class="mini-stat-label">运动速率</div>
          </div>
          <div class="mini-stat-box">
            <div class="mini-stat-value">{{ calories.toFixed(0) }}</div>
            <div class="mini-stat-label">消耗千卡</div>
          </div>
          <div class="mini-stat-box">
            <div class="mini-stat-value">--</div>
            <div class="mini-stat-label">心率</div>
          </div>
        </div>
      </div>
      
      <!-- 展开状态详细数据 -->
      <div class="panel-content" v-if="isPanelExpanded">
        <div class="stats-container">
          <div class="stat-box distance">
            <div class="stat-big-value">{{ (distance / 1000).toFixed(2) }}<span class="unit">km</span></div>
            <div class="stat-label">运动距离</div>
          </div>
          
          <div class="stats-row">
            <div class="stat-box">
              <div class="stat-value">{{ formatTime(duration) }}</div>
              <div class="stat-label">运动时间</div>
            </div>
            <div class="stat-box">
              <div class="stat-value">{{ paceFormatted }}</div>
              <div class="stat-label">运动速率</div>
            </div>
          </div>
          
          <div class="stats-row">
            <div class="stat-box">
              <div class="stat-value">{{ calories.toFixed(0) }}</div>
              <div class="stat-label">消耗千卡</div>
            </div>
            <div class="stat-box">
              <div class="stat-value">{{ currentElevation || '--' }}</div>
              <div class="stat-label">当前海拔(m)</div>
            </div>
          </div>
          
          <!-- 添加海拔图表 -->
          <div class="elevation-chart" v-if="elevationData.length > 1">
            <div class="chart-header">
              <span>海拔趋势</span>
              <div class="elevation-stats">
                <span class="stat"><strong>↑</strong> {{ totalAscent }}m</span>
                <span class="stat"><strong>↓</strong> {{ totalDescent }}m</span>
              </div>
            </div>
            <div class="chart-container">
              <svg viewBox="0 0 300 100" width="100%" height="70">
                <polyline :points="elevationChartPoints" fill="none" stroke="#1791fc" stroke-width="2" />
              </svg>
            </div>
          </div>
          
          <!-- AI教练状态面板 -->
          <div class="ai-coach-panel">
            <div class="chart-header">
              <span>AI教练分析</span>
              <div class="coach-status" :class="aiCoachEnabled ? 'active' : 'inactive'">
                {{ aiCoachEnabled ? '已启用' : '已禁用' }}
              </div>
            </div>
            
            <div class="coach-metrics" v-if="aiCoachEnabled">
              <!-- 运动强度指示器 -->
              <div class="metric-box">
                <div class="metric-label">运动强度</div>
                <div class="metric-value">
                  <div class="effort-indicator">
                    <div class="effort-level" :class="effortLevel">
                      <span v-if="effortLevel === 'easy'">轻松</span>
                      <span v-else-if="effortLevel === 'moderate'">适中</span>
                      <span v-else-if="effortLevel === 'hard'">强烈</span>
                      <span v-else>极限</span>
                    </div>
                  </div>
                </div>
              </div>
              
              <!-- 配速稳定性 -->
              <div class="metric-box">
                <div class="metric-label">配速稳定性</div>
                <div class="metric-value">
                  <div class="stability-bar">
                    <div class="stability-fill" :style="{width: `${paceStability}%`}" :class="{
                      'good': paceStability > 80,
                      'normal': paceStability > 60 && paceStability <= 80,
                      'poor': paceStability <= 60
                    }"></div>
                  </div>
                  <div class="stability-value">{{ paceStability.toFixed(0) }}%</div>
                </div>
              </div>
            </div>
            
            <div class="coach-disabled" v-else>
              <div class="disabled-message">
                <svg viewBox="0 0 24 24" width="24" height="24">
                  <path d="M12,3C10.73,3 9.6,3.8 9.18,5H3V7H4.95L2,14C1.53,16 3,17 5.5,17C8,17 9.56,16 9,14L6.05,7H9.17C9.5,7.85 10.15,8.5 11,8.83V20H2V22H22V20H13V8.82C13.85,8.5 14.5,7.85 14.82,7H17.95L15,14C14.53,16 16,17 18.5,17C21,17 22.56,16 22,14L19.05,7H21V5H14.83C14.4,3.8 13.27,3 12,3M12,5A1,1 0 0,1 13,6A1,1 0 0,1 12,7A1,1 0 0,1 11,6A1,1 0 0,1 12,5M5.5,10.25L7,14H4L5.5,10.25M18.5,10.25L20,14H17L18.5,10.25Z" fill="#999"/>
                </svg>
                <span>点击工具栏中的"AI教练"按钮启用实时跑步指导</span>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 音乐播放器内嵌 -->
        <div class="music-player-embedded">
          <div class="album-cover">
            <img :src="currentSong.cover" alt="album cover">
          </div>
          <div class="music-info">
            <div class="song-title">{{ currentSong.title }}</div>
            <div class="artist-name">{{ currentSong.artist }}</div>
          </div>
          <div class="player-controls">
            <div class="control-button prev" @click="playPrevious">
              <svg viewBox="0 0 1024 1024" width="20" height="20">
                <path d="M689.92 171.52L308.48 452.8c-15.68 11.52-15.68 34.56 0 46.08l381.44 280.96c20.48 15.36 50.56 2.56 50.56-23.04V194.56c0-25.6-30.08-38.4-50.56-23.04z" fill="#333"></path>
              </svg>
            </div>
            <div class="control-button play" @click="togglePlay">
              <svg v-if="!isPlaying" viewBox="0 0 1024 1024" width="24" height="24">
                <path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m-106.666667 256v341.333334l256-170.666667-256-170.666667z" fill="#333"></path>
              </svg>
              <svg v-else viewBox="0 0 1024 1024" width="24" height="24">
                <path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m-106.666667 256v341.333334h213.333334V341.333333h-213.333334z" fill="#333"></path>
              </svg>
            </div>
            <div class="control-button next" @click="playNext">
              <svg viewBox="0 0 1024 1024" width="20" height="20">
                <path d="M334.08 171.52L715.52 452.8c15.68 11.52 15.68 34.56 0 46.08L334.08 780.16c-20.48 15.36-50.56 2.56-50.56-23.04V194.56c0-25.6 30.08-38.4 50.56-23.04z" fill="#333"></path>
              </svg>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 按钮区域 -->
      <div class="panel-footer">
                  <!-- 添加功能按钮区 -->
          <div class="panel-tools" v-if="isRunning">
            <button class="tool-button" @click="toggleAutoPause">
              <svg viewBox="0 0 24 24" width="20" height="20">
                <path :fill="autoPauseEnabled ? '#07c160' : '#999'" d="M13,3A9,9 0 0,0 4,12H1L4.89,15.89L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,19.99 10.51,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3Z" />
              </svg>
              <span>{{ autoPauseEnabled ? '暂停已开' : '暂停已关' }}</span>
            </button>
            
            <!-- 语音反馈按钮 -->
            <button class="tool-button" @click="toggleVoiceFeedback">
              <svg viewBox="0 0 24 24" width="20" height="20">
                <path :fill="voiceFeedback ? '#07c160' : '#999'" d="M14,3.23V5.29C16.89,6.15 19,8.83 19,12C19,15.17 16.89,17.84 14,18.7V20.77C18,19.86 21,16.28 21,12C21,7.72 18,4.14 14,3.23M16.5,12C16.5,10.23 15.5,8.71 14,7.97V16C15.5,15.29 16.5,13.76 16.5,12M3,9V15H7L12,20V4L7,9H3Z" />
              </svg>
              <span>{{ voiceFeedback ? '语音反馈开' : '语音反馈关' }}</span>
            </button>
            
            <!-- AI教练按钮 -->
            <button class="tool-button" @click="toggleAICoach">
              <svg viewBox="0 0 24 24" width="20" height="20">
                <path :fill="aiCoachEnabled ? '#07c160' : '#999'" d="M12,3C10.73,3 9.6,3.8 9.18,5H3V7H4.95L2,14C1.53,16 3,17 5.5,17C8,17 9.56,16 9,14L6.05,7H9.17C9.5,7.85 10.15,8.5 11,8.83V20H2V22H22V20H13V8.82C13.85,8.5 14.5,7.85 14.82,7H17.95L15,14C14.53,16 16,17 18.5,17C21,17 22.56,16 22,14L19.05,7H21V5H14.83C14.4,3.8 13.27,3 12,3M12,5A1,1 0 0,1 13,6A1,1 0 0,1 12,7A1,1 0 0,1 11,6A1,1 0 0,1 12,5M5.5,10.25L7,14H4L5.5,10.25M18.5,10.25L20,14H17L18.5,10.25Z" />
              </svg>
              <span>{{ aiCoachEnabled ? 'AI教练开' : 'AI教练关' }}</span>
            </button>
          </div>

        <button 
          v-if="!isRunning" 
          @click="startTracking" 
          class="action-button start-button"
        >
          开始跑步
        </button>
        <button 
          v-else 
          @click="stopTracking" 
          class="action-button stop-button"
        >
          结束训练
        </button>
      </div>
    </div>
    
    <!-- 结束跑步弹窗 -->
    <div v-if="showSummary" class="summary-modal">
      <div class="summary-content">
        <h2>本次运动已结束</h2>
        <div class="summary-stats">
          
          <div class="summary-item">
            <div class="summary-value">{{ (distance / 1000).toFixed(2) }}</div>
            <div class="summary-label">运动距离(公里)</div>
          </div>
          <div class="summary-item">
            <div class="summary-value">{{ formatTime(duration) }}</div>
            <div class="summary-label">运动时间</div>
          </div>
          <div class="summary-item">
            <div class="summary-value">{{ calories.toFixed(0) }}</div>
            <div class="summary-label">消耗(千卡)</div>
          </div>
          <div class="summary-item">
            <div class="summary-value">{{ avgPace }}</div>
            <div class="summary-label">平均配速</div>
          </div>
          <div class="summary-item">
            <div class="summary-value">{{ totalAscent }}</div>
            <div class="summary-label">累计爬升(米)</div>
          </div>
          <div class="summary-item">
            <div class="summary-value">{{ totalDescent }}</div>
            <div class="summary-label">累计下降(米)</div>
          </div>
          <div class="summary-item" v-if="isTargetRunMode">
            <div class="summary-value">{{(completionRate * 100).toFixed(0)}}%</div>
            <div class="summary-label">路线完成率</div>
          </div>
        </div>
        
        <!-- 添加海拔图 -->
        <div class="elevation-summary" v-if="elevationData.length > 1">
          <h3>海拔变化</h3>
          <div class="chart-container">
            <svg viewBox="0 0 300 100" width="100%" height="100">
              <polyline :points="elevationChartPoints" fill="none" stroke="#07c160" stroke-width="2" />
              <polygon :points="`${elevationChartPoints} 300,100 0,100`" fill="rgba(7, 193, 96, 0.1)" />
            </svg>
          </div>
        </div>
        
        <!-- AI教练建议 -->
        <div class="ai-coach-summary" v-if="aiCoachEnabled">
          <h3>AI教练建议</h3>
          <div class="coach-recommendations">
            <div class="recommendation-item" v-for="(recommendation, index) in generateAIRecommendations()" :key="index">
              <div class="recommendation-bullet">•</div>
              <div class="recommendation-text">{{ recommendation }}</div>
            </div>
          </div>
        </div>
        
        <div class="summary-actions">
          <button @click="shareSummary" class="summary-button share-button">
            <svg viewBox="0 0 1024 1024" width="20" height="20">
              <path d="M752 664c-28.5 0-54.8 10-75.4 26.7L469.4 540.8a160.68 160.68 0 0 0 0-57.6l207.2-149.9C697.2 350 723.5 360 752 360c66.2 0 120-53.8 120-120s-53.8-120-120-120-120 53.8-120 120c0 11.6 1.6 22.7 4.7 33.3L439.9 415.8C410.7 377.1 364.3 352 312 352c-88.4 0-160 71.6-160 160s71.6 160 160 160c52.3 0 98.7-25.1 127.9-63.8l196.8 142.5c-3.1 10.6-4.7 21.8-4.7 33.3 0 66.2 53.8 120 120 120s120-53.8 120-120-53.8-120-120-120z" fill="#fff"/>
            </svg>
          </button>
          <button @click="saveSummary" class="summary-button save-button">完成</button>
        </div>
      </div>
    </div>
    
    <!-- 历史记录弹窗 -->
    <div v-if="showHistory" class="history-modal">
      <div class="history-content">
        <div class="history-header">
          <h2>运动记录</h2>
          <div class="close-button" @click="closeHistory">
            <svg viewBox="0 0 24 24" width="24" height="24">
              <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" fill="#333"/>
            </svg>
          </div>
        </div>
        
        <div class="history-list" v-if="savedRecords.length > 0">
          <div 
            v-for="record in savedRecords" 
            :key="record.id" 
            class="history-item"
            @click="viewRecordDetail(record)"
          >
            <div class="history-item-date">
              {{ new Date(record.date).toLocaleDateString() }}
            </div>
            <div class="history-item-stats">
              <div class="history-stat">
                <div class="stat-value">{{ (record.distance / 1000).toFixed(2) }}</div>
                <div class="stat-label">公里</div>
              </div>
              <div class="history-stat">
                <div class="stat-value">{{ formatTime(record.duration) }}</div>
                <div class="stat-label">时间</div>
              </div>
              <div class="history-stat">
                <div class="stat-value">{{ record.avgPace }}</div>
                <div class="stat-label">配速</div>
              </div>
            </div>
          </div>
        </div>
        
        <div class="empty-history" v-else>
          <div class="empty-icon">
            <svg viewBox="0 0 24 24" width="48" height="48">
              <path d="M13,3A9,9 0 0,0 4,12H1L4.89,15.89L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,19.99 10.51,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3Z" fill="#ccc"/>
            </svg>
          </div>
          <div class="empty-text">暂无运动记录</div>
        </div>
      </div>
    </div>
    
    <!-- 记录详情弹窗 -->
    <div v-if="selectedRecord" class="record-detail-modal">
      <div class="record-detail-content">
        <div class="record-detail-header">
          <div class="back-button" @click="closeRecordDetail">
            <svg viewBox="0 0 24 24" width="24" height="24">
              <path d="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z" fill="#333"/>
            </svg>
            <span>返回列表</span>
          </div>
          <div class="delete-button" @click="deleteRecord(selectedRecord.id)">
            <svg viewBox="0 0 24 24" width="20" height="20">
              <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" fill="#f44336"/>
            </svg>
          </div>
        </div>
        
        <div class="record-detail-date">
          {{ new Date(selectedRecord.date).toLocaleString() }}
        </div>
        
        <div class="record-detail-stats">
          <div class="detail-stat-box">
            <div class="detail-stat-value">{{ (selectedRecord.distance / 1000).toFixed(2) }}</div>
            <div class="detail-stat-unit">km</div>
            <div class="detail-stat-label">运动距离</div>
          </div>
          
          <div class="detail-stats-grid">
            <div class="detail-mini-stat">
              <div class="detail-mini-value">{{ formatTime(selectedRecord.duration) }}</div>
              <div class="detail-mini-label">运动时间</div>
            </div>
            <div class="detail-mini-stat">
              <div class="detail-mini-value">{{ selectedRecord.avgPace }}</div>
              <div class="detail-mini-label">平均配速</div>
            </div>
            <div class="detail-mini-stat">
              <div class="detail-mini-value">{{ selectedRecord.calories.toFixed(0) }}</div>
              <div class="detail-mini-label">消耗千卡</div>
            </div>
            <div class="detail-mini-stat" v-if="selectedRecord.totalAscent">
              <div class="detail-mini-value">{{ selectedRecord.totalAscent.toFixed(0) }}m</div>
              <div class="detail-mini-label">累计爬升</div>
            </div>
          </div>
          
          <!-- AI教练分析总结 -->
          <div class="detail-ai-analysis" v-if="selectedRecord.aiAnalysis">
            <div class="analysis-header">AI教练评估</div>
            <div class="analysis-content">
              <div class="analysis-item">
                <div class="analysis-label">配速稳定性</div>
                <div class="analysis-value">{{ selectedRecord.aiAnalysis.paceStability || 0 }}%</div>
              </div>
              <div class="analysis-item">
                <div class="analysis-label">平均强度</div>
                <div class="analysis-value">{{ selectedRecord.aiAnalysis.avgEffort || '适中' }}</div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 轨迹地图预览 -->
        <div class="track-preview-container">
          <div ref="detailMapContainer" class="detail-map-container"></div>
        </div>
        
        <!-- 海拔图 -->
        <div class="detail-elevation-chart" v-if="selectedRecord.elevationData && selectedRecord.elevationData.length > 1">
          <div class="chart-header">海拔变化</div>
          <div class="chart-container">
            <svg viewBox="0 0 300 100" width="100%" height="100">
              <polyline :points="getElevationChartPoints(selectedRecord.elevationData)" fill="none" stroke="#07c160" stroke-width="2" />
              <polygon :points="`${getElevationChartPoints(selectedRecord.elevationData)} 300,100 0,100`" fill="rgba(7, 193, 96, 0.1)" />
            </svg>
          </div>
        </div>
        
        <!-- AI教练分析详情 -->
        <div class="detail-ai-coach" v-if="selectedRecord.aiAnalysis && selectedRecord.aiAnalysis.recommendations">
          <div class="chart-header">AI教练建议</div>
          <div class="coach-recommendations">
            <div class="recommendation-item" v-for="(recommendation, index) in selectedRecord.aiAnalysis.recommendations" :key="index">
              <div class="recommendation-bullet">•</div>
              <div class="recommendation-text">{{ recommendation }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 主页视图中的历史记录入口按钮 -->
    <div class="history-button" v-if="!isRunning" @click="viewRunHistory">
      <svg viewBox="0 0 24 24" width="24" height="24">
        <path d="M13.5,8H12V13L16.28,15.54L17,14.33L13.5,12.25V8M13,3A9,9 0 0,0 4,12H1L4.96,16.03L9,12H6A7,7 0 0,1 13,6A7,7 0 0,1 20,13A7,7 0 0,1 13,20A7,7 0 0,1 6,13H4A9,9 0 0,0 13,22A9,9 0 0,0 22,13A9,9 0 0,0 13,3" fill="#ffffff"/>
      </svg>
    </div>
    
    <!-- 语音控制状态指示器 -->
    <div class="voice-indicator" v-if="isRunning && isListening">
      <svg viewBox="0 0 24 24" width="24" height="24">
        <path d="M12,2A3,3 0 0,1 15,5V11A3,3 0 0,1 12,14A3,3 0 0,1 9,11V5A3,3 0 0,1 12,2M19,11C19,14.53 16.39,17.44 13,17.93V21H11V17.93C7.61,17.44 5,14.53 5,11H7A5,5 0 0,0 12,16A5,5 0 0,0 17,11H19Z" fill="#ffffff"/>
      </svg>
      <span>语音助手已开启，说"嗨小跑"</span>
    </div>
    
    <!-- 离线地图入口按钮 -->
    <div class="offline-map-button" v-if="!isRunning" @click="showOfflineMapManager">
      <svg viewBox="0 0 24 24" width="24" height="24">
        <path d="M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z" fill="#ffffff"/>
      </svg>
    </div>
    
    <!-- 离线地图管理面板 -->
    <div v-if="showOfflineMapPanel" class="offline-map-panel">
      <div class="offline-panel-content">
        <div class="offline-panel-header">
          <h2>离线地图管理</h2>
          <div class="close-button" @click="closeOfflineMapManager">
            <svg viewBox="0 0 24 24" width="24" height="24">
              <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" fill="#333"/>
            </svg>
          </div>
        </div>
        
        <!-- 下载新离线地图区域 -->
        <div class="download-section">
          <div class="section-title">下载新离线地图</div>
          
          <div class="radius-selector">
            <div class="radius-label">覆盖范围:</div>
            <div class="radius-options">
              <button 
                v-for="radius in [2000, 5000, 10000, 20000]" 
                :key="radius"
                :class="{'active': selectedRadius === radius}"
                @click="selectedRadius = radius"
              >
                {{ radius/1000 }}公里
              </button>
            </div>
          </div>
          
          <div class="download-actions">
            <button class="download-button" @click="downloadCurrentArea" :disabled="isDownloadingMap">
              <span v-if="!isDownloadingMap">下载当前位置周边</span>
              <span v-else>下载中 ({{ downloadProgress }}%)</span>
            </button>
          </div>
          
          <div v-if="isDownloadingMap" class="progress-bar">
            <div class="progress-fill" :style="{width: `${downloadProgress}%`}"></div>
          </div>
        </div>
        
        <!-- 已下载的离线地图列表 -->
        <div class="offline-maps-list">
          <div class="section-title">已下载的离线地图</div>
          
          <div v-if="offlineMapAreas.length === 0" class="empty-list">
            <div class="empty-icon">
              <svg viewBox="0 0 24 24" width="48" height="48">
                <path d="M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z" fill="#ccc"/>
              </svg>
            </div>
            <div class="empty-text">暂无离线地图</div>
          </div>
          
          <div v-else class="map-items">
            <div v-for="area in offlineMapAreas" :key="area.id" class="map-item">
              <div class="map-info">
                <div class="map-name">{{ area.name }}</div>
                <div class="map-details">
                  <span>{{ area.size }}</span>
                  <span class="date">{{ new Date(area.date).toLocaleDateString() }}</span>
                </div>
              </div>
              <button class="delete-map-btn" @click="deleteOfflineMapArea(area.id)">
                <svg viewBox="0 0 24 24" width="20" height="20">
                  <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" fill="#f44336"/>
                </svg>
              </button>
            </div>
          </div>
        </div>
        
        <div class="offline-note">
          <p>离线地图支持在无网络环境下查看地图和记录轨迹，但不支持路线规划和搜索功能。</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted, computed, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { addPointsForExercise } from '@/utils/pointsStore';
import { getPointsMultiplier } from '@/utils/membershipStore';

// 定义全局类型
declare global {
  interface Window {
    AMap: any;
    _AMapSecurityConfig: any;
    initAMap: () => void;
    SpeechRecognition?: any;
    webkitSpeechRecognition?: any;
  }
}

// IndexedDB实用工具
const DB_NAME = 'runningApp';
const DB_VERSION = 1;
const RECORDS_STORE = 'runRecords';
const MAPS_STORE = 'offlineMaps';
const MAP_TILES_STORE = 'mapTiles';

// 打开数据库连接
const openDatabase = (): Promise<IDBDatabase> => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);
    
    // 数据库升级或创建
    request.onupgradeneeded = (event) => {
      const db = request.result;
      
      // 创建跑步记录存储
      if (!db.objectStoreNames.contains(RECORDS_STORE)) {
        const recordsStore = db.createObjectStore(RECORDS_STORE, { keyPath: 'id' });
        recordsStore.createIndex('date', 'date', { unique: false });
      }
      
      // 创建离线地图信息存储
      if (!db.objectStoreNames.contains(MAPS_STORE)) {
        db.createObjectStore(MAPS_STORE, { keyPath: 'id' });
      }
      
      // 创建地图瓦片数据存储
      if (!db.objectStoreNames.contains(MAP_TILES_STORE)) {
        const tilesStore = db.createObjectStore(MAP_TILES_STORE, { keyPath: 'url' });
        tilesStore.createIndex('areaId', 'areaId', { unique: false });
      }
    };
    
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
};

// 保存数据到指定存储
const saveToStore = async <T>(storeName: string, data: T): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readwrite');
      const store = transaction.objectStore(storeName);
      
      // 预处理数据，确保所有数据都可以被结构化克隆算法处理
      let processedData: any;
      
      if (storeName === RECORDS_STORE) {
        // 对RunRecord类型数据特殊处理
        const record = data as any;
        processedData = {
          ...record,
          // 将复杂数组转换为可序列化的简单对象
          path: record.path ? JSON.parse(JSON.stringify(record.path)) : [],
          elevationData: record.elevationData ? JSON.parse(JSON.stringify(record.elevationData)) : [],
          // 确保其他可能包含不可克隆对象的字段也被处理
          aiAnalysis: record.aiAnalysis ? JSON.parse(JSON.stringify(record.aiAnalysis)) : undefined
        };
      } else if (storeName === MAP_TILES_STORE) {
        // 对地图瓦片数据特殊处理
        const tile = data as any;
        
        // 检查tile.data类型，确保它可以被IndexedDB结构化克隆
        let tileData = tile.data;
        // Blob和ArrayBuffer可以被IndexedDB直接存储，不需要特殊处理
        // 但其他复杂对象可能需要序列化
        if (!(tileData instanceof Blob) && 
            !(tileData instanceof ArrayBuffer) && 
            typeof tileData === 'object' && 
            tileData !== null) {
          try {
            // 尝试将复杂对象转换为可序列化形式
            tileData = JSON.parse(JSON.stringify(tileData));
          } catch (e) {
            console.warn('无法序列化瓦片数据，使用原始数据');
          }
        }
        
        processedData = {
          ...tile,
          data: tileData
        };
      } else {
        // 其他类型数据，尝试通过JSON序列化/反序列化确保可克隆
        processedData = JSON.parse(JSON.stringify(data));
      }
      
      const request = store.put(processedData);
      
      request.onsuccess = () => resolve();
      request.onerror = (event) => {
        console.error('IndexedDB存储错误:', event);
        reject(request.error);
      };
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`保存到${storeName}失败:`, error);
    throw error;
  }
};

// 从存储中获取所有数据
const getAllFromStore = async <T>(storeName: string): Promise<T[]> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readonly');
      const store = transaction.objectStore(storeName);
      const request = store.getAll();
      
      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`从${storeName}获取数据失败:`, error);
    return [];
  }
};

// 删除存储中的数据
const deleteFromStore = async (storeName: string, key: string | number): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(storeName, 'readwrite');
      const store = transaction.objectStore(storeName);
      const request = store.delete(key);
      
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
      
      transaction.oncomplete = () => db.close();
    });
  } catch (error) {
    console.error(`从${storeName}删除数据失败:`, error);
    throw error;
  }
};

// 删除存储中的所有与areaId相关的瓦片
const deleteTilesByAreaId = async (areaId: string): Promise<void> => {
  try {
    const db = await openDatabase();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(MAP_TILES_STORE, 'readwrite');
      const store = transaction.objectStore(MAP_TILES_STORE);
      const index = store.index('areaId');
      const request = index.openCursor(IDBKeyRange.only(areaId));
      
      request.onsuccess = (event) => {
        const cursor = request.result;
        if (cursor) {
          cursor.delete();
          cursor.continue();
        }
      };
      
      transaction.oncomplete = () => {
        db.close();
        resolve();
      };
      
      transaction.onerror = () => reject(transaction.error);
    });
  } catch (error) {
    console.error('删除瓦片数据失败:', error);
    throw error;
  }
};

// 定义运动记录类型
interface RunRecord {
  id: string;
  date: string; // ISO格式日期
  distance: number; // 米
  duration: number; // 秒
  calories: number;
  avgPace: string;
  path: [number, number][];
  elevationData?: number[];
  totalAscent?: number;
  totalDescent?: number;
  aiAnalysis?: {
    paceStability: number; // 配速稳定性百分比
    avgEffort: string; // 平均运动强度
    recommendations?: string[]; // AI教练建议
  };
}

interface Position {
  lng: number;
  lat: number;
}

interface GeolocationResult {
  position: Position;
  accuracy: number;
}

// 定义计时器类型，避免NodeJS依赖
type TimerHandle = ReturnType<typeof setInterval>;

// 添加Kalman滤波相关接口
interface KalmanFilter {
  x: number;  // 状态
  P: number;  // 协方差
  R: number;  // 测量噪声
  Q: number;  // 过程噪声
  predict(): void;
  update(measurement: number): number;
}

export default defineComponent({
  name: 'FreeRunning',
  setup() {
    const route = useRoute();
    const router = useRouter();
    
    // 将路由参数转换为数值数组
    const initialPosition = ref<[number, number] | null>(null);
    if (route.params.position) {
      try {
        // 安全地解析路由参数
        const posArray = Array.isArray(route.params.position) 
          ? route.params.position[0].split(',') 
          : route.params.position.split(',');
        
        if (posArray.length === 2) {
          const lng = parseFloat(posArray[0]);
          const lat = parseFloat(posArray[1]);
          if (!isNaN(lng) && !isNaN(lat)) {
            initialPosition.value = [lng, lat];
          }
        }
      } catch (e) {
        console.error('解析位置参数失败:', e);
      }
    }

    // 离线地图相关状态
    const isOnline = ref(true); // 在线状态
    const isMapOfflineAvailable = ref(false); // 是否有可用的离线地图
    const offlineMapAreas = ref<Array<{
      id: string;
      name: string;
      center: [number, number];
      radius: number;
      size: string;
      date: string;
    }>>([]);
    const isDownloadingMap = ref(false); // 是否正在下载地图
    const downloadProgress = ref(0); // 下载进度
    const showOfflineMapPanel = ref(false); // 是否显示离线地图面板
    const selectedRadius = ref(5000); // 默认选择5公里半径
    
    // 面板状态控制
    const isPanelExpanded = ref(false);
    const dragStartY = ref(0);
    const dragStartTime = ref(0);
    
    // 音乐播放状态
    const isPlaying = ref(false);
    const currentSongIndex = ref(0);
    const playlist = ref([
      {
        title: '倔强',
        artist: '五月天',
        cover: '',
        src: 'https://music.163.com/song/media/outer/url?id=386538.mp3'
      },
      {
        title: '奔跑',
        artist: '羽泉',
        cover: '',
        src: 'https://music.163.com/song/media/outer/url?id=25642119.mp3'
      },

      {
        title: '最初的梦想',
        artist: '范玮琪',
        cover: '',
        src: 'https://music.163.com/song/media/outer/url?id=255858.mp3'
      },

      {
        title: '超越梦想',
        artist: '许嵩',
        cover: '',
        src: 'https://music.163.com/song/media/outer/url?id=167691.mp3'
      },

    ]);
    const currentSong = computed(() => playlist.value[currentSongIndex.value]);
    const audioElement = ref<HTMLAudioElement | null>(null);
    
    // 运动数据状态
    const distance = ref(0); // 单位：米
    const calories = ref(0); // 单位：千卡
    const duration = ref(0); // 单位：秒
    const currentSpeed = ref(0); // 单位：米/秒
    const isRunning = ref(false);
    const showSummary = ref(false);
    const map = ref<any>(null);
    const marker = ref<any>(null);
    const polyline = ref<any>(null);
    const polylineSegments = ref<any[]>([]); // 存储多段轨迹线
    const circle = ref<any>(null);
    const actualInitialPosition = ref<[number, number] | null>(null);
    const accuracy = ref<number>(0); // 精度值
    const elevationData = ref<number[]>([]); // 存储海拔数据
    const currentElevation = ref<number | null>(null); // 当前海拔
    const lastRecordedPoint = ref<[number, number] | null>(null); // 上次记录的有效轨迹点
    const directionChangeThreshold = 15; // 方向变化阈值（度）
    const minDistanceThreshold = 2; // 最小距离阈值（米）
    
    // 语音控制相关状态
    const isListening = ref(false); // 是否正在监听语音
    const recognition = ref<any>(null); // 语音识别实例
    const voiceFeedback = ref(true); // 是否启用语音反馈
    const wakeupKeyword = '嗨小跑'; // 唤醒词
    
    // AI教练相关状态
    const aiCoachEnabled = ref(true); // 是否启用AI教练功能
    const lastCoachFeedbackTime = ref(0); // 上次教练反馈时间
    const coachFeedbackInterval = 60000; // 教练反馈间隔（毫秒）
    const runningForm = ref<'good' | 'normal' | 'poor'>('normal'); // 跑步姿势评估
    const effortLevel = ref<'easy' | 'moderate' | 'hard' | 'max'>('moderate'); // 运动强度
    const paceStability = ref<number>(100); // 配速稳定性百分比
    const lastPaces = ref<number[]>([]); // 存储最近的配速数据
    
    // 目标跑相关状态
    const isTargetRunMode = ref(false);
    const targetRoute = ref<any>(null); // 目标路线
    const targetRoutePath = ref<any[]>([]); // 目标路线点集合
    const completedSegments = ref<any[]>([]); // 已完成的路段
    const completionRate = ref(0); // 路线完成率
    const searchKeyword = ref('');
    const nearbyPOIs = ref<any[]>([]);
    const destinationMarker = ref<any>(null); // 目的地标记
    const targetDistance = ref(0); // 目标路线总距离
    const showDestinationPanel = ref(true); // 控制目的地搜索面板显示/隐藏
    
    // 海拔变化统计
    const totalAscent = ref(0); // 累计上升海拔（米）
    const totalDescent = ref(0); // 累计下降海拔（米）
    
    // 为经度和纬度分别创建卡尔曼滤波器
    const kalmanLng = ref<KalmanFilter>({
      x: 0, P: 1.0, R: 0.1, Q: 0.01,
      predict() { this.P = this.P + this.Q; },
      update(measurement: number): number {
        const K = this.P / (this.P + this.R);
        this.x = this.x + K * (measurement - this.x);
        this.P = (1 - K) * this.P;
        return this.x;
      }
    });
    const kalmanLat = ref<KalmanFilter>({
      x: 0, P: 1.0, R: 0.1, Q: 0.01,
      predict() { this.P = this.P + this.Q; },
      update(measurement: number): number {
        const K = this.P / (this.P + this.R);
        this.x = this.x + K * (measurement - this.x);
        this.P = (1 - K) * this.P;
        return this.x;
      }
    });
    
    const previousPosition = ref<[number, number] | null>(null);
    const previousTime = ref<number | null>(null);
    const previousSpeed = ref<number>(0); // 添加上一次记录的速度
    const timer = ref<TimerHandle | null>(null);
    const geolocation = ref<any>(null);
    const mapContainer = ref<HTMLDivElement | null>(null);
    const path = ref<[number, number][]>([]);
    const gpsSignalStatus = ref<'strong' | 'weak' | 'lost'>('strong'); // GPS信号状态
    const lastGpsUpdateTime = ref<number>(Date.now()); // 最后一次GPS更新时间
    const gpsTimeoutThreshold = 5000; // GPS信号丢失阈值（毫秒）
    const gpsWeakThreshold = 3000; // GPS信号变弱阈值（毫秒）
    const gpsCheckInterval = ref<TimerHandle | null>(null); // GPS状态检查定时器
    
    // 自动暂停相关变量
    const isAutoPaused = ref(false); // 是否自动暂停
    const autoPauseThreshold = 5; // 自动暂停速度阈值（秒）
    const autoPauseTime = ref(0); // 用于自动暂停计算的静止时间
    const lastActiveTime = ref(Date.now()); // 上次活动时间
    const autoPauseEnabled = ref(true); // 自动暂停功能开关
    
    // 计算平均配速 (分钟/公里)
    const avgPace = computed(() => {
      if (distance.value <= 0 || duration.value <= 0) return '00:00';
      const paceSeconds = (duration.value / (distance.value / 1000));
      const paceMinutes = Math.floor(paceSeconds / 60);
      const paceRemainingSeconds = Math.floor(paceSeconds % 60);
      return `${paceMinutes.toString().padStart(2, '0')}:${paceRemainingSeconds.toString().padStart(2, '0')}`;
    });
    
    // 格式化后的配速显示
    const paceFormatted = computed(() => {
      if (currentSpeed.value <= 0.1) return "--'--\"";
      
      // 计算每公里需要的秒数
      const secondsPerKm = 1000 / currentSpeed.value;
      
      // 处理不同的运动速度情况
      if (secondsPerKm > 1800) { // 超过30分钟/公里，可能正在原地或极慢速度
        return "--'--\"";
      } else if (secondsPerKm < 120) { // 低于2分钟/公里，可能是GPS抖动
        const displaySpeed = Math.round(currentSpeed.value * 3.6); // 转换为km/h
        if (displaySpeed > 30) { // 非常快的速度，用km/h显示更直观
          return `${displaySpeed}km/h`;
        }
      }
      
      // 正常配速显示
      const minutes = Math.floor(secondsPerKm / 60);
      const seconds = Math.floor(secondsPerKm % 60);
      return `${minutes}'${seconds.toString().padStart(2, '0')}"`;
    });

    // GPS状态文本
    const gpsStatusText = computed(() => {
      switch (gpsSignalStatus.value) {
        case 'strong': return '信号良好';
        case 'weak': return '信号较弱';
        case 'lost': return '信号丢失';
        default: return '';
      }
    });

    // 返回上一页
    const goBack = () => {
      router.back();
    };
    
    // 展开面板
    const expandPanel = () => {
      isPanelExpanded.value = true;
    };
    
    // 收起面板
    const collapsePanel = () => {
      isPanelExpanded.value = false;
    };
    
    // 开始拖动
    const startDrag = (e: TouchEvent) => {
      dragStartY.value = e.touches[0].clientY;
      dragStartTime.value = Date.now();
    };
    
    // 拖动中
    const onDrag = (e: TouchEvent) => {
      const currentY = e.touches[0].clientY;
      const deltaY = currentY - dragStartY.value;
      
      // 如果向下拖动超过30px，收起面板
      if (deltaY > 30 && isPanelExpanded.value) {
        collapsePanel();
      }
      // 如果向上拖动超过30px，展开面板
      else if (deltaY < -30 && !isPanelExpanded.value) {
        expandPanel();
      }
    };
    
    // 结束拖动
    const endDrag = () => {
      // 检测是否为快速滑动
      const dragTime = Date.now() - dragStartTime.value;
      if (dragTime < 300) {
        // 快速滑动时切换面板状态
        isPanelExpanded.value = !isPanelExpanded.value;
      }
    };

    // 计算两点间距离（Haversine公式）
    const calculateDistance = (pos1: [number, number], pos2: [number, number]): number => {
      const [lng1, lat1] = pos1;
      const [lng2, lat2] = pos2;

      const earthRadius = 6371000;
      const lat1Rad = (lat1 * Math.PI) / 180;
      const lat2Rad = (lat2 * Math.PI) / 180;
      const deltaLatRad = ((lat2 - lat1) * Math.PI) / 180;
      const deltaLngRad = ((lng2 - lng1) * Math.PI) / 180;

      const a =
        Math.sin(deltaLatRad / 2) * Math.sin(deltaLatRad / 2) +
        Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.sin(deltaLngRad / 2) * Math.sin(deltaLngRad / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

      return earthRadius * c;
    };

    // 基于距离计算热量消耗（更准确的方法）
    const calculateCaloriesFromDistance = (distance: number, weight: number = 70): number => {
      // 跑步热量消耗大约为1kcal/kg/km
      // 这里使用更精确的公式：热量(kcal) = 距离(km) × 体重(kg) × 1.036
      const runningCoefficient = 1.036;
      return (distance / 1000) * weight * runningCoefficient;
    };

    // 格式化时间
    const formatTime = (seconds: number): string => {
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    };
    
    // 目标跑模式相关函数
    // 切换到自由跑模式
    const switchToFreeRun = () => {
      isTargetRunMode.value = false;
      clearTargetRoute();
    };

    // 切换到目标跑模式
    const switchToTargetRun = () => {
      isTargetRunMode.value = true;
      showDestinationPanel.value = true; // 显示目的地搜索面板
      
      // 如果已经有定位，自动搜索附近POI
      if (actualInitialPosition.value) {
        searchNearbyPOIs(actualInitialPosition.value);
      }
    };

    // 清除目标路线
    const clearTargetRoute = () => {
      if (targetRoute.value) {
        map.value.remove(targetRoute.value);
        targetRoute.value = null;
      }
      
      // 清除已完成路段
      if (completedSegments.value.length > 0) {
        completedSegments.value.forEach(segment => {
          if (segment) map.value.remove(segment);
        });
        completedSegments.value = [];
      }
      
      // 清除目的地标记
      if (destinationMarker.value) {
        map.value.remove(destinationMarker.value);
        destinationMarker.value = null;
      }
      
      targetRoutePath.value = [];
      completionRate.value = 0;
    };

    // 搜索目的地
    const searchDestination = () => {
      if (!window.AMap || !map.value) {
        showToast('地图尚未初始化完成');
        return;
      }
      
      if (!searchKeyword.value.trim()) {
        showToast('请输入搜索关键词');
        return;
      }
      
      try {
        // 清除之前的搜索结果
        nearbyPOIs.value = [];
        
        // 确保PlaceSearch插件已加载
        if (!window.AMap.PlaceSearch) {
          window.AMap.plugin('AMap.PlaceSearch', function() {
            console.log('PlaceSearch插件加载成功');
            doSearch();
          });
        } else {
          doSearch();
        }
        
        function doSearch() {
          try {
            const placeSearch = new window.AMap.PlaceSearch({
              pageSize: 10,
              pageIndex: 1,
              city: "全国"
            });
            
            showToast('正在搜索...');
            
            placeSearch.search(searchKeyword.value, (status: string, result: any) => {
              if (status === 'complete' && result.poiList && result.poiList.pois.length > 0) {
                const pois = result.poiList.pois.map((poi: any) => {
                  // 计算与当前位置的距离
                  const poiPosition = [poi.location.lng, poi.location.lat];
                  const dist = actualInitialPosition.value 
                    ? calculateDistance(actualInitialPosition.value as any, poiPosition as any)
                    : 0;
                    
                  let distanceText = '';
                  if (dist < 1000) {
                    distanceText = `${Math.round(dist)}米`;
                  } else {
                    distanceText = `${(dist / 1000).toFixed(1)}公里`;
                  }
                  
                  return {
                    id: poi.id,
                    name: poi.name,
                    location: poiPosition,
                    distance: distanceText,
                    rawDistance: dist
                  };
                });
                
                // 按距离排序
                pois.sort((a: any, b: any) => a.rawDistance - b.rawDistance);
                nearbyPOIs.value = pois;
              } else {
                showToast('未找到相关地点');
                nearbyPOIs.value = [];
              }
            });
          } catch (innerError) {
            console.error('执行搜索失败:', innerError);
            showToast('搜索功能暂时不可用，请稍后再试');
          }
        }
      } catch (error) {
        console.error('搜索地点失败:', error);
        showToast('搜索服务初始化失败');
      }
    };

    // 搜索附近POI
    const searchNearbyPOIs = (position: [number, number]) => {
      if (!window.AMap || !map.value) {
        showToast('地图尚未初始化完成，请稍后再试');
        return;
      }
      
      try {
        // 确保PlaceSearch插件已加载
        if (!window.AMap.PlaceSearch) {
          window.AMap.plugin('AMap.PlaceSearch', function() {
            console.log('PlaceSearch插件加载成功');
            doSearch();
          });
        } else {
          doSearch();
        }
        
        function doSearch() {
          try {
            const placeSearch = new window.AMap.PlaceSearch({
              type: '餐饮服务|购物服务|旅游景点|运动健身场所',
              pageSize: 10,
              pageIndex: 1
            });
            
            placeSearch.searchNearBy('', position, 5000, (status: string, result: any) => {
              if (status === 'complete' && result.poiList && result.poiList.pois.length > 0) {
                const pois = result.poiList.pois.map((poi: any) => {
                  // 计算与当前位置的距离
                  let distanceText = '';
                  if (poi.distance < 1000) {
                    distanceText = `${Math.round(poi.distance)}米`;
                  } else {
                    distanceText = `${(poi.distance / 1000).toFixed(1)}公里`;
                  }
                  
                  return {
                    id: poi.id,
                    name: poi.name,
                    location: [poi.location.lng, poi.location.lat],
                    distance: distanceText,
                    rawDistance: poi.distance
                  };
                });
                
                nearbyPOIs.value = pois;
              } else {
                showToast('附近未找到兴趣点');
                nearbyPOIs.value = [];
              }
            });
          } catch (innerError) {
            console.error('执行搜索失败:', innerError);
            showToast('搜索功能暂时不可用，请稍后再试');
          }
        }
      } catch (error) {
        console.error('搜索附近POI失败:', error);
        showToast('搜索服务初始化失败');
      }
    };

    // 选择目的地并规划路线
    const selectDestination = (poi: any) => {
      if (!actualInitialPosition.value || !map.value) return;
      
      // 关闭目的地搜索面板
      showDestinationPanel.value = false;
      
      // 清除之前的路线
      clearTargetRoute();
      
      // 显示目的地标记
      if (window.AMap) {
        // 确保位置格式正确
        let destPosition: any;
        if (Array.isArray(poi.location)) {
          destPosition = poi.location;
        } else if (poi.location && typeof poi.location.lng !== 'undefined') {
          destPosition = [poi.location.lng, poi.location.lat];
        } else {
          console.error('无效的位置格式');
          return;
        }
        
        destinationMarker.value = new window.AMap.Marker({
          position: destPosition,
          map: map.value,
          title: poi.name,
          icon: new window.AMap.Icon({
            size: new window.AMap.Size(25, 34),
            image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
            imageSize: new window.AMap.Size(25, 34)
          })
        });
        
        // 规划路线
        planRoute(actualInitialPosition.value, destPosition, poi.name);
      }
    };

    // 规划路线
    const planRoute = (start: [number, number] | any, end: any, destName: string) => {
      if (!window.AMap || !map.value) {
        showToast('地图尚未初始化完成');
        return;
      }
      
      try {
        // 确保Driving插件已加载
        if (!window.AMap.Driving) {
          window.AMap.plugin('AMap.Driving', function() {
            console.log('Driving插件加载成功');
            doDriving();
          });
        } else {
          doDriving();
        }
        
        function doDriving() {
          try {
            // 创建路线规划实例
            const driving = new window.AMap.Driving({
              map: map.value,
              panel: false,
              policy: window.AMap.DrivingPolicy.LEAST_TIME
            });
        
        // 规划路线
        driving.search(start, end, {}, (status: string, result: any) => {
          if (status === 'complete' && result.routes && result.routes.length > 0) {
            // 提取路线点
            const routeInfo = result.routes[0];
            let path: any[] = [];
            
            // 从路线结果中提取路径点
            routeInfo.steps.forEach((step: any) => {
              path = path.concat(step.path);
            });
            
            targetRoutePath.value = path;
            targetDistance.value = routeInfo.distance;
            
            // 显示路线
            showTargetRoute(path);
            
            // 显示路线信息
            showToast(`已设置路线: ${destName}, 距离: ${(routeInfo.distance/1000).toFixed(2)}公里`);
            
            // 调整地图视图以适应路线
            const fitOverlays = [];
            if (destinationMarker.value) fitOverlays.push(destinationMarker.value);
            if (targetRoute.value) fitOverlays.push(targetRoute.value);
            if (fitOverlays.length > 0) {
              map.value.setFitView(fitOverlays);
            }
          } else {
            showToast('路线规划失败，请重新选择目的地');
          }
        });
          } catch (innerError) {
            console.error('规划路线失败:', innerError);
            showToast('路线规划功能暂时不可用');
          }
        }
      } catch (error) {
        console.error('路线规划出错:', error);
        showToast('路线规划失败，请重试');
      }
    };

    // 在地图上显示目标路线
    const showTargetRoute = (path: any[]) => {
      if (!map.value) return;
      
      targetRoute.value = new window.AMap.Polyline({
        path: path,
        strokeColor: '#3366FF',
        strokeOpacity: 0.8,
        strokeWeight: 6,
        strokeStyle: 'solid',
        lineJoin: 'round',
        lineCap: 'round',
        zIndex: 50,
        map: map.value
      });
    };

    // 检查路线完成情况
    const checkRouteProgress = (currentPosition: any) => {
      if (!targetRoutePath.value.length) return;
      
      // 查找最近的路径点和距离
      const { nearestIdx, minDistance } = findNearestPointOnPath(currentPosition);
      
      // 如果没找到有效点，返回
      if (nearestIdx < 0) return;
      
      // 如果距离路线太远，不计算进度
      const maxDistanceThreshold = 30; // 允许偏离路线的最大距离（米）
      if (minDistance > maxDistanceThreshold) return;
      
      // 标记已完成的路段
      markSegmentsAsCompleted(nearestIdx);
      
      // 计算完成率
      const totalPoints = targetRoutePath.value.length;
      completionRate.value = Math.min(1, (nearestIdx + 1) / totalPoints);
    };

    // 找到路径上距离当前位置最近的点
    const findNearestPointOnPath = (position: any) => {
      const path = targetRoutePath.value;
      let minDistance = Infinity;
      let nearestIdx = -1;
      
      path.forEach((point, index) => {
        // 安全获取路径点坐标
        let lng = 0, lat = 0;
        if (typeof point.lng !== 'undefined') {
          lng = point.lng;
          lat = point.lat;
        } else if (Array.isArray(point) && point.length >= 2) {
          lng = point[0];
          lat = point[1];
        }
        const pathPoint: [number, number] = [lng, lat];
        
        // 安全获取当前位置坐标
        let posLng = 0, posLat = 0;
        if (Array.isArray(position) && position.length >= 2) {
          posLng = position[0];
          posLat = position[1];
        } else if (position && typeof position.lng !== 'undefined') {
          posLng = position.lng;
          posLat = position.lat;
        }
        const posPoint: [number, number] = [posLng, posLat];
        
        const distance = calculateDistance(posPoint, pathPoint);
        
        if (distance < minDistance) {
          minDistance = distance;
          nearestIdx = index;
        }
      });
      
      return { nearestIdx, minDistance };
    };

    // 标记已完成的路段
    const markSegmentsAsCompleted = (currentIdx: number) => {
      if (!map.value || currentIdx <= 0) return;
      
      // 移除现有的已完成路段
      completedSegments.value.forEach(segment => {
        if (segment) map.value.remove(segment);
      });
      completedSegments.value = [];
      
      // 创建新的已完成路段（灰色）
      // 安全地复制路径点
      const completedPath: any[] = [];
      for (let i = 0; i <= currentIdx; i++) {
        const point = targetRoutePath.value[i];
        if (point) completedPath.push(point);
      }
      
      const completedSegment = new window.AMap.Polyline({
        path: completedPath,
        strokeColor: '#999999', // 灰色
        strokeOpacity: 0.8,
        strokeWeight: 6,
        strokeStyle: 'solid',
        lineJoin: 'round',
        lineCap: 'round',
        zIndex: 51, // 确保在目标路线之上
        map: map.value
      });
      
      completedSegments.value.push(completedSegment);
    };

    // 根据速度获取轨迹颜色
    const getSpeedColor = (speed: number): string => {
      if (speed < 1) return '#3366FF'; // 慢速/步行 - 蓝色
      if (speed < 2.5) return '#33CC33'; // 慢跑 - 绿色
      if (speed < 4) return '#FFCC00'; // 中速跑 - 黄色
      if (speed < 6) return '#FF9900'; // 快跑 - 橙色
      return '#FF3300'; // 冲刺 - 红色
    };

    // 计算两点间方向角度
    const calculateBearing = (pos1: [number, number], pos2: [number, number]): number => {
      const [lng1, lat1] = pos1;
      const [lng2, lat2] = pos2;
      
      const lat1Rad = (lat1 * Math.PI) / 180;
      const lat2Rad = (lat2 * Math.PI) / 180;
      const lngDiffRad = ((lng2 - lng1) * Math.PI) / 180;
      
      const y = Math.sin(lngDiffRad) * Math.cos(lat2Rad);
      const x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - 
                Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(lngDiffRad);
      
      let bearing = Math.atan2(y, x) * 180 / Math.PI;
      if (bearing < 0) bearing += 360;
      
      return bearing;
    };
    
    // 检查是否需要记录新点
    const shouldRecordPoint = (newPosition: [number, number]): boolean => {
      if (!lastRecordedPoint.value) return true;
      
      // 计算与上一个点的距离
      const distanceDelta = calculateDistance(lastRecordedPoint.value, newPosition);
      
      // 如果距离过小，不记录
      if (distanceDelta < minDistanceThreshold) return false;
      
      // 如果有一定距离，检查方向变化
      if (previousPosition.value && lastRecordedPoint.value) {
        const previousBearing = calculateBearing(previousPosition.value, lastRecordedPoint.value);
        const currentBearing = calculateBearing(lastRecordedPoint.value, newPosition);
        const bearingChange = Math.abs(previousBearing - currentBearing);
        
        // 如果方向有显著变化，记录点
        if (bearingChange > directionChangeThreshold) return true;
      }
      
      // 基于当前速度动态调整采样频率
      const samplingDistance = Math.max(
        minDistanceThreshold, 
        Math.min(currentSpeed.value * 1.5, 10) // 速度越快，采样距离越大，但最大10米
      );
      
      return distanceDelta > samplingDistance;
    };

    // 创建新的轨迹段
    const createNewTrackSegment = (startPosition: [number, number], speed: number) => {
      if (!map.value) return null;
      
      const segmentColor = getSpeedColor(speed);
      
      const newSegment = new window.AMap.Polyline({
        path: [startPosition],
        strokeColor: segmentColor,
        strokeWeight: 6,
        strokeOpacity: 0.8,
        strokeStyle: "solid",
        lineJoin: "round",
        lineCap: "round",
        zIndex: 50,
        map: map.value,
        showDir: false,       // 不显示方向箭头
        geodesic: false,      // 不使用大地线计算
        zooms: [3, 20],       // 设置可见级别
        renderOptions: {      // 渲染选项
          pathTolerance: 2,   // 简化轨迹点的阈值
          simplify: true      // 开启轨迹简化
        }
      });
      
      // 记录初始更新时间
      newSegment._lastUpdateTime = Date.now();
      
      polylineSegments.value.push(newSegment);
      return newSegment;
    };
    
    // 处理位置更新
    const handlePositionUpdate = (result: GeolocationResult): void => {
      // 更新GPS信号状态
      gpsSignalStatus.value = 'strong';
      lastGpsUpdateTime.value = Date.now();
      
      const rawPosition: [number, number] = [result.position.lng, result.position.lat];
      const now = Date.now();
      const currentAccuracy = result.accuracy;
      accuracy.value = currentAccuracy;

      // 如果精度太差，可能是GPS漂移，跳过此次更新
      if (currentAccuracy > 50) { // 精度超过50米时认为不可靠
        console.log('GPS精度过低，忽略此次更新');
        return;
      }

      // 应用Kalman滤波
      if (kalmanLng.value.x === 0 && kalmanLat.value.x === 0) {
        // 首次初始化滤波器
        kalmanLng.value.x = rawPosition[0];
        kalmanLat.value.x = rawPosition[1];
      } else {
        kalmanLng.value.predict();
        kalmanLat.value.predict();
        
        // 根据精度动态调整测量噪声
        const accuracyFactor = Math.max(5, Math.min(20, currentAccuracy)) / 10;
        kalmanLng.value.R = 0.05 * accuracyFactor; // 降低基础噪声
        kalmanLat.value.R = 0.05 * accuracyFactor;
        
        // 根据速度动态调整过程噪声 - 速度快时允许更快地跟踪变化
        if (currentSpeed.value > 3) { // 速度较快时
          kalmanLng.value.Q = 0.01;
          kalmanLat.value.Q = 0.01;
        } else { // 速度较慢或静止时
          kalmanLng.value.Q = 0.005;
          kalmanLat.value.Q = 0.005;
        }
        
        rawPosition[0] = kalmanLng.value.update(rawPosition[0]);
        rawPosition[1] = kalmanLat.value.update(rawPosition[1]);
      }
      
      const newPosition: [number, number] = [rawPosition[0], rawPosition[1]];

      // 更新标记位置 - 减少不必要的更新
      if (marker.value) {
        // 只有当位置变化超过一定阈值时才更新标记位置，减少渲染
        if (!previousPosition.value || 
            calculateDistance(previousPosition.value, newPosition) > 1) {
          marker.value.setPosition(newPosition);
        }
      }

      // 更新精度圆位置和半径 - 减少不必要的更新
      if (circle.value) {
        // 只有当位置变化超过一定阈值或精度变化较大时才更新圆
        if (!previousPosition.value || 
            calculateDistance(previousPosition.value, newPosition) > 1 ||
            Math.abs(circle.value.getRadius() - currentAccuracy) > 5) {
          circle.value.setCenter(newPosition);
          circle.value.setRadius(currentAccuracy);
        }
      }

      // 判断是否应该记录此点
      let shouldAdd = false;
      if (isRunning.value && shouldRecordPoint(newPosition)) {
        // 记录此点但不立即添加到轨迹线
        path.value.push(newPosition);
        lastRecordedPoint.value = newPosition;
        shouldAdd = true;
      }
      
      // 计算运动数据
      if (previousPosition.value && previousTime.value) {
        const distanceDelta = calculateDistance(previousPosition.value, newPosition);
        
        // 过滤异常值 - 更严格的速度限制
        const timeDelta = (now - previousTime.value) / 1000;
        const speed = timeDelta > 0 ? distanceDelta / timeDelta : 0;
        
        // 更严格的速度过滤 - 考虑上一次速度进行平滑过渡
        const maxSpeedChange = 3; // 每秒最大速度变化（m/s²）
        const maxAllowedSpeed = Math.min(8, currentSpeed.value + maxSpeedChange * timeDelta); // 动态最大速度
        const isValidSpeed = speed <= maxAllowedSpeed;
        
        // 处理自动暂停检测
        if (autoPauseEnabled.value && isRunning.value) {
          if (speed < 0.5) { // 低于0.5m/s约等于步行很慢或静止
            if (!isAutoPaused.value) {
              autoPauseTime.value += timeDelta;
              // 如果静止时间超过阈值，触发自动暂停
              if (autoPauseTime.value >= autoPauseThreshold) {
                isAutoPaused.value = true;
                showToast('检测到您已停止移动，计时已自动暂停');
              }
            }
          } else {
            // 如果有移动，重置静止时间并恢复计时
            if (isAutoPaused.value) {
              isAutoPaused.value = false;
              showToast('检测到您开始移动，计时已恢复');
            }
            autoPauseTime.value = 0;
            lastActiveTime.value = now;
          }
        }
        
        // AI教练分析 - 记录配速数据用于分析
        if (isRunning.value && !isAutoPaused.value && isValidSpeed && speed > 0.5) {
          // 计算当前配速（秒/公里）
          const currentPace = speed > 0 ? 1000 / speed : 0;
          
          // 记录最近的配速数据（最多保存10个数据点）
          if (currentPace > 0) {
            lastPaces.value.push(currentPace);
            if (lastPaces.value.length > 10) {
              lastPaces.value.shift();
            }
            
            // 分析配速稳定性
            if (lastPaces.value.length >= 3) {
              const paceVariance = calculatePaceVariance(lastPaces.value);
              // 配速稳定性评分 (100% 表示完全稳定)
              paceStability.value = Math.max(0, Math.min(100, 100 - paceVariance * 10));
              
              // 评估运动强度
              updateEffortLevel(currentPace);
            }
          }
          
          // 检查是否需要提供教练反馈
          const now = Date.now();
          if (aiCoachEnabled.value && now - lastCoachFeedbackTime.value > coachFeedbackInterval) {
            provideCoachFeedback();
            lastCoachFeedbackTime.value = now;
          }
        }
        
        if (isValidSpeed) { // 使用更严格的速度验证
          // 只有当速度合理时才更新距离
          const newDistance = distance.value + distanceDelta;
          distance.value = newDistance;

          // 基于累计距离重新计算总热量
          const newCalories = calculateCaloriesFromDistance(newDistance);
          calories.value = newCalories;
          
          // 改进的速度计算 - 使用自适应权重
          if (speed > 0.2) { // 只有当速度不接近静止时才更新
            // 根据速度变化幅度动态调整权重
            const speedDiff = Math.abs(speed - currentSpeed.value);
            const weightForNew = Math.max(0.3, Math.min(0.7, 0.5 - speedDiff / 10));
            
            // 应用平滑过滤
            currentSpeed.value = currentSpeed.value * (1 - weightForNew) + speed * weightForNew;
          } else {
            // 当几乎静止时，速度应该快速衰减到接近0
            currentSpeed.value = currentSpeed.value * 0.3;
            if (currentSpeed.value < 0.2) currentSpeed.value = 0;
          }
          
          // 基于速度创建新轨迹段或更新现有段 - 减少轨迹段创建频率
          if (shouldAdd && isRunning.value) {
            const currentColor = getSpeedColor(currentSpeed.value);
            
            // 降低创建新段的频率 - 每1000米或更大速度变化时创建新段
            const needNewSegment = polylineSegments.value.length === 0 || 
                                  distance.value % 1000 < distanceDelta ||
                                  Math.abs(currentSpeed.value - (previousSpeed?.value || 0)) > 2.5;
            
            if (needNewSegment) {
              const newSegment = createNewTrackSegment(newPosition, currentSpeed.value);
              // 保存当前速度用于下次比较
              previousSpeed.value = currentSpeed.value;
            } else {
              // 更新现有段
              const currentSegment = polylineSegments.value[polylineSegments.value.length - 1];
              
              // 批量更新轨迹点，而不是每次都更新
              // 每隔几个点更新一次，或者累积一定时间后更新
              if (now - (currentSegment._lastUpdateTime || 0) > 300) { // 至少300ms更新一次
                const currentPath = currentSegment.getPath();
                currentPath.push(newPosition);
                currentSegment.setPath(currentPath);
                
                // 记录最后更新时间
                currentSegment._lastUpdateTime = now;
                
                // 如果速度变化较大，更新颜色
                const segmentColor = currentSegment.getOptions().strokeColor;
                if (segmentColor !== currentColor) {
                  currentSegment.setOptions({ strokeColor: currentColor });
                }
              }
            }
          }
        } else {
          console.log('检测到异常速度，可能是GPS漂移，已过滤:', speed);
        }
      } else if (isRunning.value && path.value.length === 1) {
        // 如果是第一个点，创建初始轨迹段
        createNewTrackSegment(newPosition, 0);
      }

      // 移动地图中心并调整视角 - 优化版本
      if (map.value) {
        // 减少地图中心更新频率，使用节流策略
        const mapUpdateThreshold = 2; // 地图更新阈值（米）
        if (!previousPosition.value || 
            calculateDistance(previousPosition.value, newPosition) > mapUpdateThreshold) {
          // 平滑移动地图中心
          map.value.setCenter(newPosition);
          
          // 调整地图倾斜角度，提供更好的3D体验，但减少更新频率
          if (isRunning.value && path.value.length > 2) {
            // 计算移动方向，调整地图视角，但降低更新频率
            const lastIdx = path.value.length - 1;
            if (lastIdx >= 1 && path.value.length % 3 === 0) { // 每3个点更新一次方向
              const p1 = path.value[lastIdx - 1];
              const p2 = path.value[lastIdx];
              const angle = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI;
              map.value.setRotation(90 - angle); // 使地图朝向前进方向
            }
          }
        }
      }

      previousPosition.value = newPosition;
      previousTime.value = now;
      
      // 添加目标路径完成检测
      if (isTargetRunMode.value && targetRoutePath.value.length > 0 && isRunning.value) {
        checkRouteProgress(newPosition as any);
      }

      // 请求海拔数据（如果支持）
      if ('altitude' in result.position) {
        const elevation = (result.position as any).altitude;
        // 处理海拔数据
        if (typeof elevation === 'number' && !isNaN(elevation)) {
          // 记录当前海拔
          currentElevation.value = Math.round(elevation);
          
          // 添加到海拔数据数组（按距离采样，而非时间）
          if (shouldRecordPoint(newPosition) && isRunning.value) {
            // 当添加轨迹点时同时记录海拔
            elevationData.value.push(elevation);
            
            // 计算海拔变化
            if (elevationData.value.length > 1) {
              const prevElevation = elevationData.value[elevationData.value.length - 2];
              const elevationChange = elevation - prevElevation;
              
              // 记录上升或下降
              if (elevationChange > 0.5) { // 超过0.5米视为有效上升
                totalAscent.value += elevationChange;
              } else if (elevationChange < -0.5) { // 超过0.5米视为有效下降
                totalDescent.value += Math.abs(elevationChange);
              }
            }
          }
        }
      } else {
        // 如果设备不支持海拔数据，可以通过高德地图API获取（需要额外调用）
        // 使用高德地图API获取DEM数据
        if (window.AMap && window.AMap.plugin && shouldRecordPoint(newPosition) && isRunning.value) {
          window.AMap.plugin(['AMap.Geolocation'], function() {
            const geocoder = new window.AMap.Geocoder();
            geocoder.getAddress(newPosition, (status: string, result: any) => {
              if (status === 'complete' && result.regeocode) {
                if (result.regeocode.addressComponent && result.regeocode.addressComponent.businessAreas) {
                  // 尝试从返回结果中提取海拔数据（如果有）
                  // 注意：实际使用时可能需要使用专门的海拔API
                  const elevation = 0; // 占位，实际中需要替换为真实数据
                  if (typeof elevation === 'number') {
                    currentElevation.value = Math.round(elevation);
                    elevationData.value.push(elevation);
                  }
                }
              }
            });
          });
        }
      }
    };

    // 检查GPS信号状态
    const checkGpsStatus = () => {
      if (!isRunning.value) return;
      
      const now = Date.now();
      const timeSinceLastUpdate = now - lastGpsUpdateTime.value;
      
      if (timeSinceLastUpdate > gpsTimeoutThreshold) {
        // GPS信号丢失
        if (gpsSignalStatus.value !== 'lost') {
          gpsSignalStatus.value = 'lost';
          // 显示提示
          showToast('GPS信号丢失，请移动到开阔地区');
        }
      } else if (timeSinceLastUpdate > gpsWeakThreshold) {
        // GPS信号弱
        gpsSignalStatus.value = 'weak';
      }
    };
    
    // 简单的Toast提示实现
    const toastMessage = ref('');
    const showingToast = ref(false);
    const showToast = (message: string) => {
      toastMessage.value = message;
      showingToast.value = true;
      setTimeout(() => {
        showingToast.value = false;
      }, 3000);
    };
    
    // 开始运动追踪 - 优化版本
    const startTracking = (): void => {
      if (!actualInitialPosition.value || !geolocation.value) {
        showToast('定位服务尚未准备好，请稍后再试');
        return;
      }
      
      // 检查浏览器是否支持地理位置API
      if (!('geolocation' in navigator)) {
        showToast('您的浏览器不支持地理位置功能，无法使用跑步功能');
        return;
      }

      isRunning.value = true;
      isPanelExpanded.value = false; // 收起面板
      
      // 如果是目标跑模式但没有设置路线，提示用户
      if (isTargetRunMode.value && (!targetRoute.value || targetRoutePath.value.length === 0)) {
        showToast('请先设置目标路线');
        isRunning.value = false;
        return;
      }
      
      // 初始化音频播放器
      initAudio();
      
      // 重置数据
      path.value = [];
      polylineSegments.value = []; // 清空轨迹段
      lastRecordedPoint.value = null;
      
      // 如果是目标跑模式，重置进度
      if (isTargetRunMode.value) {
        completionRate.value = 0;
        // 清除已完成路段
        completedSegments.value.forEach(segment => {
          if (segment) map.value.remove(segment);
        });
        completedSegments.value = [];
        
        // 将地图视图调整为显示整个路线
        if (targetRoute.value && destinationMarker.value) {
          const overlays = [];
          if (targetRoute.value) overlays.push(targetRoute.value);
          if (destinationMarker.value) overlays.push(destinationMarker.value);
          map.value.setFitView(overlays);
        }
        
        // 添加目标距离提示
        showToast(`开始目标跑步，总距离: ${(targetDistance.value/1000).toFixed(2)}公里`);
      }
      
      // 添加初始位置作为第一个点
      if (actualInitialPosition.value) {
        const initialPoint: [number, number] = [actualInitialPosition.value[0], actualInitialPosition.value[1]];
        path.value.push(initialPoint);
      }
      previousPosition.value = actualInitialPosition.value;
      previousTime.value = Date.now();
      distance.value = 0;
      calories.value = 0;
      duration.value = 0;
      currentSpeed.value = 0;
      elevationData.value = [];
      totalAscent.value = 0;
      totalDescent.value = 0;
      
      // 重置卡尔曼滤波器
      if (actualInitialPosition.value) {
        kalmanLng.value.x = actualInitialPosition.value[0];
        kalmanLat.value.x = actualInitialPosition.value[1];
        kalmanLng.value.P = 1.0;
        kalmanLat.value.P = 1.0;
      }

      // 重置自动暂停相关变量
      isAutoPaused.value = false;
      autoPauseTime.value = 0;
      lastActiveTime.value = Date.now();
      
      // 添加GPS信号监控
      gpsCheckInterval.value = setInterval(checkGpsStatus, 1000);
      
      // 开始计时
      timer.value = setInterval(() => {
        // 只有在未暂停状态下才增加时间
        if (!isAutoPaused.value && !(gpsSignalStatus.value === 'lost' && (Date.now() - lastGpsUpdateTime.value) > 30000)) {
          duration.value++;
        }
      }, 1000);

      // 开始高德定位 - 优化定位参数
      geolocation.value.watchPosition({
        enableHighAccuracy: true,
        timeout: 5000,        // 缩短超时时间
        maximumAge: 1000,     // 允许使用1秒内的缓存位置
        convert: true,
        interval: 1000,       // 设置定位间隔为1秒，减少过于频繁的更新
      }, (status: string, result: GeolocationResult) => {
        if (status === 'complete') {
          handlePositionUpdate(result);
        } else {
          console.error('定位失败:', result);
        }
      });
      
      // 设置地图为3D视角
      if (map.value) {
        map.value.setPitch(50); // 设置倾斜角度
        
        // 降低地图渲染负担
        map.value.setStatus({
          animateEnable: false,  // 关闭动画效果
          dragEnable: false      // 运动时禁止拖拽，减少额外渲染
        });
      }
      
      // 初始化语音控制
      initSpeechRecognition();
      
      // 播放语音提示
      speakText(`跑步已开始，说"${wakeupKeyword}"可以激活语音控制`);
      
      // 如果AI教练已开启，提供初始反馈
      if (aiCoachEnabled.value) {
        setTimeout(() => {
          speakText('AI教练已启动，将在跑步过程中为您提供指导');
          lastCoachFeedbackTime.value = Date.now();
        }, 5000); // 5秒后播报，避免与开始提示重叠
      }
    };

    // 停止运动追踪 - 优化版本
    const stopTracking = (): void => {
      isRunning.value = false;
      if (timer.value) clearInterval(timer.value);
      if (geolocation.value) {
        geolocation.value.clearWatch();
      }
      
      // 停止语音识别
      if (recognition.value && isListening.value) {
        try {
          recognition.value.stop();
        } catch (e) {
          console.error('停止语音识别失败:', e);
        }
        isListening.value = false;
      }
      
      // 显示运动总结
      showSummary.value = true;
      
      // 如果是目标跑模式，记录路线完成率
      if (isTargetRunMode.value) {
        console.log(`目标路线完成率: ${(completionRate.value * 100).toFixed(0)}%`);
      }
      
      // 调整地图视角以显示整个轨迹
      if (map.value && polylineSegments.value.length > 0) {
        try {
          // 不传参数让地图自动适应所有覆盖物
          map.value.setFitView(null, false, [60, 60, 60, 60]);
          map.value.setPitch(0); // 恢复平面视角
          map.value.setRotation(0); // 恢复正北朝向
          
          // 恢复地图交互功能
          map.value.setStatus({
            animateEnable: true,
            dragEnable: true
          });
        } catch (error) {
          console.error('调整地图视角错误:', error);
          // 出错时至少恢复到初始位置
          if (actualInitialPosition.value) {
            map.value.setCenter(actualInitialPosition.value);
          }
        }
      }
      
      // 清除GPS检查定时器
      if (gpsCheckInterval.value) {
        clearInterval(gpsCheckInterval.value);
      }
    };
    
    // 分享运动记录
    const shareSummary = () => {
      console.log('分享运动记录');
      // 这里可以添加分享功能的实现
    };
    
    // 保存运动记录
    const saveSummary = () => {
      // 创建AI分析数据
      const aiAnalysisData = aiCoachEnabled.value ? {
        paceStability: paceStability.value,
        avgEffort: effortLevel.value === 'easy' ? '轻松' : 
                  effortLevel.value === 'moderate' ? '适中' : 
                  effortLevel.value === 'hard' ? '强烈' : '极限',
        recommendations: generateAIRecommendations()
      } : undefined;
      
      // 创建新记录
      const newRecord: RunRecord = {
        id: `run-${Date.now()}`,
        date: new Date().toISOString(),
        distance: distance.value,
        duration: duration.value,
        calories: calories.value,
        avgPace: avgPace.value,
        path: path.value,
        elevationData: elevationData.value,
        totalAscent: totalAscent.value,
        totalDescent: totalDescent.value,
        aiAnalysis: aiAnalysisData
      };
      
      // 添加到历史记录
      addNewRecord(newRecord);
      
      // 关闭总结弹窗
      closeSummary();
      
      // 显示提示
      showToast('运动记录已保存');
    };
    
    // 生成AI教练建议
    const generateAIRecommendations = (): string[] => {
      const recommendations: string[] = [];
      
      // 根据本次跑步表现生成个性化建议
      if (paceStability.value < 70) {
        recommendations.push('尝试使用节奏器或音乐来保持更稳定的配速');
      }
      
      if (effortLevel.value === 'hard' && duration.value > 1800) { // 30分钟以上高强度
        recommendations.push('考虑增加恢复跑，避免连续高强度训练');
      }
      
      if (totalAscent.value > 100) { // 有较多爬升
        recommendations.push('爬坡训练对提升耐力很有帮助，可以定期加入');
      }
      
      // 添加通用建议
      const generalTips = [
        '每周保持3-4次跑步，循序渐进增加距离',
        '注意跑步姿势，保持上身挺直，步频适中',
        '交替进行长距离慢跑和短距离速度训练',
        '跑前热身和跑后拉伸同样重要'
      ];
      
      // 随机选择1-2条通用建议
      const tipCount = Math.floor(Math.random() * 2) + 1;
      for (let i = 0; i < tipCount; i++) {
        const randomIndex = Math.floor(Math.random() * generalTips.length);
        const tip = generalTips.splice(randomIndex, 1)[0];
        recommendations.push(tip);
      }
      
      return recommendations;
    };
    
    // 关闭总结弹窗
    const closeSummary = () => {
      showSummary.value = false;
    };

    // 音乐播放控制
    const initAudio = () => {
      if (!audioElement.value) {
        audioElement.value = new Audio();
        
        // 添加事件监听
        audioElement.value.addEventListener('ended', () => {
          // 播放结束自动切换到下一首
          playNext();
        });
        
        audioElement.value.addEventListener('error', (e) => {
          console.error('音乐播放错误:', e);
          isPlaying.value = false;
          showToast('音乐加载失败，自动切换到下一首');
          // 出错时自动切换到下一首
          setTimeout(() => playNext(), 1000);
        });
      }
      
      // 更新当前歌曲
      updateCurrentAudio();
    };
    
    // 更新当前播放的音频
    const updateCurrentAudio = () => {
      if (!audioElement.value) return;
      
      // 暂停当前播放
      audioElement.value.pause();
      
      // 更新音频源
      audioElement.value.src = currentSong.value.src;
      
      // 如果当前是播放状态，则加载并播放新歌曲
      if (isPlaying.value) {
        audioElement.value.load();
        
        // 使用用户交互事件处理音频播放，避免自动播放策略限制
        const playPromise = audioElement.value.play();
        if (playPromise !== undefined) {
          playPromise.catch(error => {
            console.error('播放失败:', error);
            if (error.name === 'NotAllowedError') {
              showToast('浏览器阻止了自动播放，请点击播放按钮手动播放');
              isPlaying.value = false;
            } else {
              showToast('播放失败，尝试下一首歌曲');
              // 如果播放失败，尝试下一首
              setTimeout(() => playNext(), 1000);
            }
          });
        }
      }
      
      // 显示当前播放信息
      showToast(`当前歌曲: ${currentSong.value.title} - ${currentSong.value.artist}`);
    };
    
    // 模拟播放功能 - 在网络环境不佳或音频加载失败时使用
    const simulatePlay = () => {
      isPlaying.value = !isPlaying.value;
      
      if (isPlaying.value) {
        showToast(`模拟播放: ${currentSong.value.title} - ${currentSong.value.artist}`);
      } else {
        showToast('音乐已暂停');
      }
    };
    
    const togglePlay = () => {
      if (!audioElement.value) {
        initAudio();
      }
      
      try {
        if (isPlaying.value) {
          audioElement.value?.pause();
          isPlaying.value = false;
          showToast('音乐已暂停');
        } else {
          // 尝试播放音频
          if (audioElement.value) {
            audioElement.value.play().catch(error => {
              console.error('播放失败:', error);
              // 如果播放失败，使用模拟播放
              simulatePlay();
            });
            isPlaying.value = true;
            showToast(`播放: ${currentSong.value.title}`);
          } else {
            // 如果音频元素不存在，使用模拟播放
            simulatePlay();
          }
        }
      } catch (error) {
        console.error('播放操作错误:', error);
        // 出现任何错误，使用模拟播放
        simulatePlay();
      }
    };
    
    const playPrevious = () => {
      // 切换到上一首歌
      currentSongIndex.value = (currentSongIndex.value - 1 + playlist.value.length) % playlist.value.length;
      updateCurrentAudio();
    };
    
    const playNext = () => {
      // 切换到下一首歌
      currentSongIndex.value = (currentSongIndex.value + 1) % playlist.value.length;
      updateCurrentAudio();
    };

    // 添加自动暂停开关控制
    const toggleAutoPause = () => {
      autoPauseEnabled.value = !autoPauseEnabled.value;
      showToast(autoPauseEnabled.value ? '自动暂停功能已开启' : '自动暂停功能已关闭');
    };

    // 初始化地图
    onMounted(() => {
      // 安全配置 - 从配置中获取
      // 在实际项目中，应该将这些值放在环境变量中
      const securityJsCode = "bc85185b03fc9a32c0a1f023a1addd87";
      const mapApiKey = "0710f43e6881294242c7d4d1eb47d192";
      
      window._AMapSecurityConfig = {
        securityJsCode: securityJsCode
      };

      // 初始化网络监听
      setupNetworkListener();
      
      // 初始化离线地图功能
      initOfflineMapFeature();
      
      // 加载历史记录
      loadRunHistory();
      
      // 检查网络状态，决定如何加载地图
      if (navigator.onLine) {
        loadOnlineMap();
      } else {
        // 离线状态，尝试加载离线地图
        checkOfflineMaps().then(hasOfflineMaps => {
          if (hasOfflineMaps) {
            // 有离线地图数据，尝试加载离线地图
            initOfflineMapInstance();
          } else {
            // 没有离线地图，仍然尝试加载在线地图，但设置较短的超时
            loadOnlineMap(5000); // 5秒超时
          }
        });
      }
    });
    
    // 加载在线地图
    const loadOnlineMap = (timeout = 15000) => {
      const mapApiKey = "0710f43e6881294242c7d4d1eb47d192";
      
      // 设置加载超时
      const timeoutId = setTimeout(() => {
        console.warn("地图API加载超时，尝试使用离线地图");
        // 如果超时，检查是否有离线地图可用
        checkOfflineMaps().then(hasOfflineMaps => {
          if (hasOfflineMaps) {
            initOfflineMapInstance();
          } else {
            showToast('地图加载失败，请检查网络连接');
          }
        });
      }, timeout);
      
      // 加载高德地图脚本
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.async = true;
      script.src = `https://webapi.amap.com/maps?v=2.0&key=${mapApiKey}&plugin=AMap.Geolocation,AMap.Marker,AMap.Polyline,AMap.Circle,AMap.Scale,AMap.ControlBar,AMap.PlaceSearch,AMap.Driving&callback=initAMap`;
      
      // 定义全局回调函数
      window.initAMap = () => {
        console.log("地图API加载成功");
        // 清除超时计时器
        clearTimeout(timeoutId);
        initMapInstance();
      };
      
      script.onerror = (e) => {
        console.error("地图API加载失败:", e);
        // 清除超时计时器
        clearTimeout(timeoutId);
        
        // 尝试使用离线地图
        checkOfflineMaps().then(hasOfflineMaps => {
          if (hasOfflineMaps) {
            initOfflineMapInstance();
          } else {
            showToast('地图加载失败，请检查网络连接');
          }
        });
      };
      
      document.head.appendChild(script);
    };
    
    // 初始化地图实例
    const initMapInstance = () => {
      const AMap = window.AMap;
      if (!AMap) {
        console.error("AMap未加载");
        return;
      }
      
      // 确保所有必要的插件都已加载
      AMap.plugin(['AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Driving'], function() {
        console.log('插件加载成功');
      });
      
      // 创建地图实例
      const mapInstance = new AMap.Map(mapContainer.value, {
        zoom: 18,
        viewMode: "3D", // 设置为3D视图
        pitch: 45,      // 设置初始俯仰角
        rotateEnable: true,
        pitchEnable: true,
        buildingAnimation: false, // 关闭建筑物动画效果以提高性能
        expandZoomRange: true,
        zooms: [3, 20],
        mapStyle: 'amap://styles/normal',
        features: ['bg', 'road', 'building', 'point'],
        showBuildingBlock: true, // 显示建筑物块
        showIndoorMap: false,    // 关闭室内图以提高性能
        preloadMode: false,      // 关闭预加载模式
        dragEnable: true,
        keyboardEnable: false,   // 关闭键盘控制
        doubleClickZoom: false,  // 关闭双击缩放
        jogEnable: false,        // 关闭地图倾斜效果
        resizeEnable: true,
        touchZoom: true
      });
      
      // 添加控件
      const controlBar = new AMap.ControlBar({
        position: {
          right: '10px',
          top: '10px'
        },
        showZoomBar: true,
        showControlButton: true
      });
      mapInstance.addControl(controlBar);
      
      // 添加比例尺
      const scale = new AMap.Scale({
        position: {
          left: '10px',
          bottom: '10px'
        }
      });
      mapInstance.addControl(scale);
      
      // 初始化定位服务 - 优化参数
      const geo = new AMap.Geolocation({
        enableHighAccuracy: true,
        timeout: 5000,        // 缩短超时时间，更快返回结果
        maximumAge: 1000,     // 允许使用1秒内的缓存位置
        convert: true,
        showButton: false,
        showMarker: false,
        showCircle: false,
        panToLocation: true,
        zoomToAccuracy: true,
        GeoLocationFirst: true // 优先使用GPS定位
      });
      
      // 获取初始位置
      const getInitialPosition = (): Promise<[number, number]> => {
        return new Promise((resolve, reject) => {
          if (initialPosition.value) {
            resolve(initialPosition.value);
          } else {
            geo.getCurrentPosition((status: string, result: GeolocationResult) => {
              if (status === 'complete') {
                const position: [number, number] = [result.position.lng, result.position.lat];
                accuracy.value = result.accuracy; // 记录初始精度
                resolve(position);
              } else {
                reject(new Error('获取当前位置失败'));
              }
            });
          }
        });
      };
      
      // 获取位置并初始化地图组件
      getInitialPosition().then((position) => {
        actualInitialPosition.value = position;
        mapInstance.setCenter(position);
        
        // 初始化卡尔曼滤波器
        kalmanLng.value.x = position[0];
        kalmanLat.value.x = position[1];
        
        // 创建自定义定位点
        const markerContent = document.createElement('div');
        markerContent.className = 'location-marker';
        
        // 创建标记
        const markerInstance = new AMap.Marker({
          position,
          content: markerContent,
          offset: new AMap.Pixel(-8, -8),
          zIndex: 200,
          map: mapInstance
        });
        
        // 创建轨迹线 - 使用初始位置创建有效路径
        const initialPath = [[position[0], position[1]], [position[0], position[1]]];
        const polylineInstance = new AMap.Polyline({
          path: initialPath, // 使用有效的初始路径（两个相同的点）
          strokeColor: "#07c160", // 绿色轨迹
          strokeWeight: 6,
          strokeOpacity: 0.8,
          strokeStyle: "solid",
          lineJoin: "round",
          lineCap: "round",
          zIndex: 50,
          map: mapInstance
        });
        
        // 创建精度圆
        const circleInstance = new AMap.Circle({
          center: position,
          radius: accuracy.value,
          strokeColor: "#1791fc",
          strokeWeight: 2,
          strokeOpacity: 0.6,
          fillColor: "#1791fc",
          fillOpacity: 0.1,
          zIndex: 10,
          map: mapInstance
        });
        
        map.value = mapInstance;
        marker.value = markerInstance;
        polyline.value = polylineInstance;
        circle.value = circleInstance;
        geolocation.value = geo;
        
        // 地图加载完成后的事件
        mapInstance.on('complete', () => {
          console.log('地图加载完成');
        });
      }).catch((error) => {
        console.error('初始化地图失败:', error);
      });
    };

    // 清理资源
    onUnmounted(() => {
      if (timer.value) clearInterval(timer.value);
      if (geolocation.value) {
        geolocation.value.clearWatch();
      }
      if (map.value) map.value.destroy();
      
      // 清理音频资源
      if (audioElement.value) {
        audioElement.value.pause();
        audioElement.value.src = '';
        audioElement.value.remove();
        audioElement.value = null;
      }
    });

    // 海拔图表数据点
    const elevationChartPoints = computed(() => {
      // 检查是否有足够的数据点
      if (!elevationData.value || elevationData.value.length < 2) return '';
      
      try {
        // 过滤掉无效数据
        const validElevations = elevationData.value.filter(el => 
          typeof el === 'number' && !isNaN(el) && isFinite(el));
        
        // 如果过滤后的数据不足，返回空
        if (validElevations.length < 2) return '';
        
        // 找出最高和最低海拔值以确定比例
        const maxElevation = Math.max(...validElevations);
        const minElevation = Math.min(...validElevations);
        const elevationRange = Math.max(maxElevation - minElevation, 10); // 至少10米范围
        
        // 计算点坐标
        const points: string[] = [];
        const width = 300;
        const height = 100;
        const segmentWidth = width / (validElevations.length - 1);
        
        validElevations.forEach((elevation, index) => {
          const x = index * segmentWidth;
          // 反转Y坐标（SVG的0点在顶部）并缩放到图表高度
          const y = height - ((elevation - minElevation) / elevationRange * height * 0.8 + height * 0.1);
          points.push(`${x.toFixed(1)},${y.toFixed(1)}`); // 使用toFixed减少数值精度
        });
        
        return points.join(' ');
      } catch (error) {
        console.error('计算海拔图表数据点错误:', error);
        return '';
      }
    });

    // 历史记录相关
    const savedRecords = ref<RunRecord[]>([]);
    const showHistory = ref(false);
    const selectedRecord = ref<RunRecord | null>(null);
    
    // 加载历史记录
    const loadRunHistory = async () => {
      try {
        // 优先从IndexedDB加载
        const records = await getAllFromStore<RunRecord>(RECORDS_STORE);
        if (records && records.length > 0) {
          // 按日期降序排序
          records.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
          savedRecords.value = records;
          console.log('从IndexedDB加载了', records.length, '条跑步记录');
        } else {
          // 如果IndexedDB中没有数据，尝试从localStorage迁移
          const storedRecords = localStorage.getItem('runningHistory');
          if (storedRecords) {
            const legacyRecords = JSON.parse(storedRecords);
            savedRecords.value = legacyRecords;
            
            // 将旧数据迁移到IndexedDB
            for (const record of legacyRecords) {
              await saveToStore(RECORDS_STORE, record);
            }
            
            console.log('已将', legacyRecords.length, '条历史记录从localStorage迁移至IndexedDB');
            // 可以选择迁移后清除localStorage中的数据
            // localStorage.removeItem('runningHistory');
          }
        }
      } catch (e) {
        console.error('加载历史记录失败:', e);
        // 出错时尝试从localStorage加载
        const storedRecords = localStorage.getItem('runningHistory');
        if (storedRecords) {
          savedRecords.value = JSON.parse(storedRecords);
          showToast('从本地缓存加载了历史记录');
        }
      }
    };
    
    // 保存历史记录
    const saveRunHistory = async () => {
      try {
        // 将所有记录保存到IndexedDB
        for (const record of savedRecords.value) {
          await saveToStore(RECORDS_STORE, record);
        }
        
        // 同时保存到localStorage作为备份
        try {
          localStorage.setItem('runningHistory', JSON.stringify(savedRecords.value));
        } catch (localError) {
          console.warn('备份到localStorage失败，可能是因为数据量过大:', localError);
        }
      } catch (e) {
        console.error('保存历史记录到IndexedDB失败:', e);
        showToast('保存记录失败，请稍后再试');
        
        // 出错时尝试保存到localStorage
        try {
          localStorage.setItem('runningHistory', JSON.stringify(savedRecords.value));
        } catch (localError) {
          showToast('保存记录失败，存储空间可能已满');
        }
      }
    };
    
    // 添加新记录
    const addNewRecord = async (record: RunRecord) => {
      // 添加到内存中的列表
      savedRecords.value.unshift(record); // 添加到列表开头
      
      // 限制存储记录数量，避免存储空间溢出
      if (savedRecords.value.length > 100) {
        savedRecords.value = savedRecords.value.slice(0, 100);
      }
      
      try {
        // 预处理路径数据，确保它是简单的可序列化数组
        // 这是一个额外的保护措施，防止在saveToStore之前就出现问题
        if (record.path && Array.isArray(record.path)) {
          // 确保path是简单数组而非包含引用或复杂对象的数组
          const simplePath = record.path.map(point => {
            // 确保每个点是简单的数组，而不是复杂对象
            if (Array.isArray(point) && point.length >= 2) {
              return [Number(point[0]), Number(point[1])]; // 确保是数字
            } else if (typeof point === 'object' && point !== null) {
              // 如果点是对象（如AMap.LngLat），提取经纬度值
              const pointObj = point as any; // 使用any类型避免类型检查错误
              return [Number(pointObj.lng || 0), Number(pointObj.lat || 0)];
            }
            return [0, 0]; // 默认值，避免null
          });
          
          record.path = simplePath as [number, number][];
        }
        
        // 保存到IndexedDB
        await saveToStore(RECORDS_STORE, record);
        console.log('成功保存跑步记录到IndexedDB:', record.id);
        
        // 同步更新全部记录
        await saveRunHistory();
      } catch (e) {
        console.error('保存新记录到IndexedDB失败:', e);
        showToast('记录已保存到内存，但数据库存储失败');
        
        // 出错时尝试使用localStorage备份机制
        try {
          // 尝试对记录进行简化，移除可能导致问题的复杂对象
          const simplifiedRecord = {
            id: record.id,
            date: record.date,
            distance: record.distance,
            duration: record.duration,
            calories: record.calories,
            avgPace: record.avgPace,
            // 确保保存成功最基本的数据，可能会丢失一些复杂数据
          };
          
          const safeRecords = savedRecords.value.map(r => ({
            id: r.id,
            date: r.date,
            distance: r.distance,
            duration: r.duration,
            calories: r.calories,
            avgPace: r.avgPace
          }));
          
          localStorage.setItem('runningHistory', JSON.stringify(safeRecords));
        } catch (localError) {
          console.error('localStorage备份也失败:', localError);
          showToast('保存记录失败，请检查存储空间');
        }
      }
    };
    
    // 查看历史记录
    const viewRunHistory = () => {
      showHistory.value = true;
    };
    
    // 关闭历史记录
    const closeHistory = () => {
      showHistory.value = false;
    };
    
    // 查看特定记录详情
    const viewRecordDetail = (record: RunRecord) => {
      selectedRecord.value = record;
      
      // 在下一个渲染循环中初始化地图
      nextTick(() => {
        if (detailMapContainer.value && record.path.length > 0) {
          // 加载地图
          initDetailMap(record);
        }
      });
    };
    
    // 关闭记录详情
    const closeRecordDetail = () => {
      if (detailMap.value) {
        detailMap.value.destroy();
        detailMap.value = null;
      }
      selectedRecord.value = null;
    };
    
    // 删除记录
    const deleteRecord = async (id: string) => {
      const index = savedRecords.value.findIndex(r => r.id === id);
      if (index !== -1) {
        // 从内存中删除
        savedRecords.value.splice(index, 1);
        
        try {
          // 从IndexedDB中删除
          await deleteFromStore(RECORDS_STORE, id);
          console.log('成功从IndexedDB删除记录:', id);
          
          // 同步更新localStorage备份
          try {
            localStorage.setItem('runningHistory', JSON.stringify(savedRecords.value));
          } catch (localError) {
            console.warn('更新localStorage备份失败:', localError);
          }
          
          // 如果是当前查看的记录，关闭详情面板
          if (selectedRecord.value?.id === id) {
            selectedRecord.value = null;
          }
          
          showToast('记录已删除');
        } catch (e) {
          console.error('从IndexedDB删除记录失败:', e);
          // 出错时回退内存中的更改
          loadRunHistory();
          showToast('删除失败，请稍后再试');
        }
      }
    };

    // 详情页地图实例
    const detailMapContainer = ref<HTMLDivElement | null>(null);
    const detailMap = ref<any>(null);
    
    // 生成历史记录的海拔图点
    const getElevationChartPoints = (elevationData: number[]): string => {
      if (!elevationData || elevationData.length < 2) return '';
      
      const maxElevation = Math.max(...elevationData);
      const minElevation = Math.min(...elevationData);
      const elevationRange = Math.max(maxElevation - minElevation, 10);
      
      const points: string[] = [];
      const width = 300;
      const height = 100;
      const segmentWidth = width / (elevationData.length - 1);
      
      elevationData.forEach((elevation, index) => {
        const x = index * segmentWidth;
        const y = height - ((elevation - minElevation) / elevationRange * height * 0.8 + height * 0.1);
        points.push(`${x},${y}`);
      });
      
      return points.join(' ');
    };
    
    // 初始化详情地图
    const initDetailMap = (record: RunRecord) => {
      if (!window.AMap) {
        console.error("高德地图API尚未加载");
        return;
      }
      
      if (detailMap.value) {
        // 如果已存在，则销毁重建
        detailMap.value.destroy();
      }
      
      detailMap.value = new window.AMap.Map(detailMapContainer.value, {
        zoom: 14,
        viewMode: "2D",
        mapStyle: 'amap://styles/normal'
      });
      
      // 绘制轨迹
      if (record.path && record.path.length > 1) {
        const polyline = new window.AMap.Polyline({
          path: record.path,
          strokeColor: "#07c160",
          strokeWeight: 6,
          strokeOpacity: 0.8,
          zIndex: 50
        });
        
        detailMap.value.add(polyline);
        
        // 起点和终点标记
        const startIcon = new window.AMap.Icon({
          size: new window.AMap.Size(25, 34),
          imageSize: new window.AMap.Size(25, 34),
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/start.png'
        });
        
        const endIcon = new window.AMap.Icon({
          size: new window.AMap.Size(25, 34),
          imageSize: new window.AMap.Size(25, 34),
          image: 'https://webapi.amap.com/theme/v1.3/markers/n/end.png'
        });
        
        const startMarker = new window.AMap.Marker({
          position: record.path[0],
          icon: startIcon,
          offset: new window.AMap.Pixel(-13, -34)
        });
        
        const endMarker = new window.AMap.Marker({
          position: record.path[record.path.length - 1],
          icon: endIcon,
          offset: new window.AMap.Pixel(-13, -34)
        });
        
        detailMap.value.add([startMarker, endMarker]);
        
        // 自动调整视图以适合轨迹
        detailMap.value.setFitView();
      }
    };

    // 处理语音命令
    const processVoiceCommand = (command: string) => {
      console.log('处理语音命令:', command);
      
      // 匹配命令并执行相应操作
      if (command.includes('距离') || command.includes('跑了多远')) {
        const distanceKm = (distance.value / 1000).toFixed(2);
        speakText(`当前距离${distanceKm}公里`);
        return true;
      } 
      else if (command.includes('时间') || command.includes('跑了多久')) {
        speakText(`跑步时间${formatTime(duration.value)}`);
        return true;
      }
      else if (command.includes('配速') || command.includes('速度')) {
        speakText(`当前配速${paceFormatted.value}`);
        return true;
      }
      else if (command.includes('暂停音乐') || command.includes('停止音乐')) {
        if (isPlaying.value) {
          togglePlay();
          speakText('音乐已暂停');
          return true;
        }
      }
      else if (command.includes('播放音乐') || command.includes('继续音乐')) {
        if (!isPlaying.value) {
          togglePlay();
          speakText('音乐已播放');
          return true;
        }
      }
      else if (command.includes('下一首')) {
        playNext();
        speakText('播放下一首');
        return true;
      }
      else if (command.includes('上一首')) {
        playPrevious();
        speakText('播放上一首');
        return true;
      }
      else if (command.includes('结束跑步') || command.includes('停止跑步')) {
        speakText('结束跑步');
        stopTracking();
        return true;
      }
      else if (command.includes('打开自动暂停') || command.includes('启用自动暂停')) {
        if (!autoPauseEnabled.value) {
          autoPauseEnabled.value = true;
          speakText('自动暂停已开启');
          return true;
        }
      }
      else if (command.includes('关闭自动暂停') || command.includes('禁用自动暂停')) {
        if (autoPauseEnabled.value) {
          autoPauseEnabled.value = false;
          speakText('自动暂停已关闭');
          return true;
        }
      }
      // AI教练相关命令
      else if (command.includes('打开教练') || command.includes('启用教练') || command.includes('开启AI教练')) {
        if (!aiCoachEnabled.value) {
          toggleAICoach();
          return true;
        }
      }
      else if (command.includes('关闭教练') || command.includes('禁用教练') || command.includes('关闭AI教练')) {
        if (aiCoachEnabled.value) {
          toggleAICoach();
          return true;
        }
      }
      else if (command.includes('教练建议') || command.includes('给点建议') || command.includes('跑步建议')) {
        // 立即提供一次教练反馈
        provideCoachFeedback();
        return true;
      }
      else if (command.includes('我的状态') || command.includes('运动状态')) {
        // 提供当前运动状态综合报告
        let status = `您当前的配速是${paceFormatted.value}，`;
        
        // 添加强度评估
        if (effortLevel.value === 'easy') {
          status += '处于轻松跑状态，';
        } else if (effortLevel.value === 'moderate') {
          status += '处于中等强度状态，';
        } else if (effortLevel.value === 'hard') {
          status += '处于高强度状态，';
        }
        
        // 添加配速稳定性评价
        if (paceStability.value > 85) {
          status += '配速非常稳定。';
        } else if (paceStability.value > 70) {
          status += '配速比较稳定。';
        } else {
          status += '配速波动较大。';
        }
        
        speakText(status);
        return true;
      }
      else if (command.includes('帮助') || command.includes('有什么功能')) {
        speakText('您可以询问距离、时间、配速，控制音乐播放，或者说教练建议获取跑步指导');
        return true;
      }
      
      // 不支持的命令不进行回复
      return false;
    };
    
    // 初始化语音识别
    const initSpeechRecognition = () => {
      // 兼容不同浏览器
      const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
      if (!SpeechRecognition) {
        showToast('您的浏览器不支持语音识别功能');
        voiceFeedback.value = false; // 自动关闭语音反馈
        console.error('浏览器不支持SpeechRecognition API');
        return;
      }
      
      recognition.value = new SpeechRecognition();
      recognition.value.continuous = true; // 持续监听
      recognition.value.interimResults = false; // 只返回最终结果
      recognition.value.lang = 'zh-CN'; // 设置语言为中文
      
      // 处理识别结果
      recognition.value.onresult = (event: any) => {
        const transcript = event.results[event.results.length - 1][0].transcript.trim().toLowerCase();
        console.log('识别到语音:', transcript);
        
        // 检测唤醒词
        if (transcript.includes(wakeupKeyword.toLowerCase())) {
          showToast('语音助手已激活，请说出命令');
          speakText('我在听');
        } else {
          // 处理语音命令，不支持的命令不回复
          processVoiceCommand(transcript);
        }
      };
      
      recognition.value.onerror = (event: any) => {
        console.error('语音识别错误:', event.error);
        if (event.error === 'no-speech') {
          // 没有检测到语音，重新启动
          restartSpeechRecognition();
        } else if (event.error === 'aborted' || event.error === 'network') {
          // 网络错误或被中断，尝试重新启动
          setTimeout(() => {
            restartSpeechRecognition();
          }, 3000);
        }
      };
      
      recognition.value.onend = () => {
        // 如果跑步仍在进行，则重新启动语音识别
        if (isRunning.value) {
          restartSpeechRecognition();
        }
      };
      
      // 启动语音识别
      startSpeechRecognition();
    };
    
    // 启动语音识别
    const startSpeechRecognition = () => {
      if (!recognition.value) return;
      
      try {
        recognition.value.start();
        isListening.value = true;
        console.log('语音识别已启动');
      } catch (e) {
        console.error('启动语音识别失败:', e);
      }
    };
    
    // 重新启动语音识别（处理自动断开的情况）
    const restartSpeechRecognition = () => {
      if (!isRunning.value) return;
      
      // 短暂延迟后重新启动
      setTimeout(() => {
        if (recognition.value && !isListening.value) {
          try {
            recognition.value.start();
            isListening.value = true;
            console.log('语音识别已重新启动');
          } catch (e) {
            console.error('重新启动语音识别失败:', e);
          }
        }
      }, 300);
    };
    
    // 文字转语音
    const speakText = (text: string) => {
      if (!voiceFeedback.value) return;
      
      // 先暂停语音识别，避免自己的声音被捕获
      if (recognition.value && isListening.value) {
        try {
          recognition.value.stop();
          isListening.value = false;
        } catch (e) {
          console.error('暂停语音识别失败:', e);
        }
      }
      
      const speech = new SpeechSynthesisUtterance();
      speech.text = text;
      speech.lang = 'zh-CN';
      speech.volume = 1;
      speech.rate = 1;
      speech.pitch = 1;
      
      // 语音播放结束后恢复语音识别
      speech.onend = () => {
        // 短暂延迟后重启语音识别，确保语音播放完全结束
        setTimeout(() => {
          if (isRunning.value) {
            restartSpeechRecognition();
          }
        }, 500);
      };
      
      window.speechSynthesis.speak(speech);
    };

    // 切换语音反馈
    const toggleVoiceFeedback = () => {
      voiceFeedback.value = !voiceFeedback.value;
      showToast(voiceFeedback.value ? '语音反馈已开启' : '语音反馈已关闭');
    };
    
    // AI教练功能相关函数
    
    // 计算配速方差 - 用于评估配速稳定性
    const calculatePaceVariance = (paces: number[]): number => {
      if (paces.length < 2) return 0;
      
      // 计算平均配速
      const avgPace = paces.reduce((sum, pace) => sum + pace, 0) / paces.length;
      
      // 计算方差
      const variance = paces.reduce((sum, pace) => {
        const diff = pace - avgPace;
        return sum + (diff * diff);
      }, 0) / paces.length;
      
      // 返回标准差的归一化值 (0-10 范围内)
      return Math.min(10, Math.sqrt(variance) / 30);
    };
    
    // 更新运动强度评估
    const updateEffortLevel = (currentPace: number): void => {
      // 根据配速评估运动强度 (配速越低，强度越大)
      if (currentPace < 240) { // 4:00 min/km以下，高强度
        effortLevel.value = 'hard';
      } else if (currentPace < 300) { // 5:00 min/km以下，中等强度
        effortLevel.value = 'moderate';
      } else if (currentPace < 420) { // 7:00 min/km以下，低强度
        effortLevel.value = 'easy';
      } else {
        effortLevel.value = 'easy'; // 步行或极慢跑
      }
      
      // 如果心率数据可用，可以在这里结合心率进行更准确的评估
    };
    
    // 提供教练反馈
    const provideCoachFeedback = (): void => {
      if (!aiCoachEnabled.value || !voiceFeedback.value || !isRunning.value || isAutoPaused.value) return;
      
      // 根据当前数据生成教练反馈
      let feedback = '';
      
      // 1. 配速稳定性反馈
      if (paceStability.value < 60) {
        feedback = '您的配速波动较大，尝试保持更稳定的步频和步幅';
      } else if (paceStability.value > 90) {
        feedback = '您的配速非常稳定，保持得很好';
      }
      
      // 2. 运动强度反馈
      if (effortLevel.value === 'hard' && duration.value > 600) { // 10分钟以上高强度
        feedback = '您已保持高强度运动一段时间，注意控制呼吸和节奏';
      } else if (effortLevel.value === 'easy' && distance.value > 3000) { // 3公里以上低强度
        feedback = '如果感觉良好，可以尝试稍微提高配速，增加训练效果';
      }
      
      // 3. 里程碑鼓励
      if (Math.abs(distance.value % 1000) < 50) { // 接近整公里数
        const kmReached = Math.floor(distance.value / 1000);
        feedback = `恭喜您，已完成${kmReached}公里！保持良好状态`;
      }
      
      // 4. 随机鼓励语
      if (!feedback && Math.random() < 0.3) { // 30%几率给出随机鼓励
        const encouragements = [
          '保持良好节奏，您的表现很棒',
          '注意呼吸，保持步伐均匀',
          '放松肩膀，保持上身挺直',
          '专注当下，享受跑步的感觉',
          '您的坚持正在转化为进步'
        ];
        feedback = encouragements[Math.floor(Math.random() * encouragements.length)];
      }
      
      // 如果有反馈，通过语音播报
      if (feedback) {
        speakText(feedback);
      }
    };
    
    // 切换AI教练功能
    const toggleAICoach = () => {
      aiCoachEnabled.value = !aiCoachEnabled.value;
      showToast(aiCoachEnabled.value ? 'AI教练已开启' : 'AI教练已关闭');
      
      // 如果开启，立即给出一次反馈
      if (aiCoachEnabled.value && isRunning.value) {
        setTimeout(() => {
          speakText('AI教练已启动，将为您提供实时跑步指导');
          lastCoachFeedbackTime.value = Date.now();
        }, 1000);
      }
    };

    // 网络状态监听
    const setupNetworkListener = () => {
      // 初始网络状态
      isOnline.value = navigator.onLine;
      
      // 添加网络状态变化监听
      window.addEventListener('online', () => {
        isOnline.value = true;
        showToast('网络已恢复，切换到在线模式');
        
        // 如果当前没有地图实例或者是离线地图模式，尝试加载在线地图
        if (!map.value || (map.value && map.value.isOfflineMode)) {
          loadOnlineMap();
        }
      });
      
      window.addEventListener('offline', () => {
        isOnline.value = false;
        showToast('网络已断开，切换到离线模式');
        
        // 检查是否有离线地图
        checkOfflineMaps().then(hasOfflineMaps => {
          // 如果有离线地图且当前没有地图或者不是离线模式，切换到离线地图
          if (hasOfflineMaps && (!map.value || (map.value && !map.value.isOfflineMode))) {
            // 如果当前有在线地图实例，先销毁它
            if (map.value && !map.value.isOfflineMode) {
              try {
                map.value.destroy();
                map.value = null;
              } catch (e) {
                console.error('销毁在线地图实例失败:', e);
              }
            }
            
            // 初始化离线地图
            initOfflineMapInstance();
          } else if (!hasOfflineMaps) {
            showToast('无可用的离线地图，部分功能可能不可用');
          }
        });
      });
    };
    
    // 检查是否有可用的离线地图，返回布尔值表示是否有可用离线地图
    const checkOfflineMaps = async (): Promise<boolean> => {
      try {
        // 优先从IndexedDB加载离线地图区域信息
        interface OfflineMapArea {
          id: string;
          name: string;
          center: [number, number];
          radius: number;
          size: string;
          date: string;
        }
        
        const areas = await getAllFromStore<OfflineMapArea>(MAPS_STORE);
        if (areas && areas.length > 0) {
          offlineMapAreas.value = areas;
          isMapOfflineAvailable.value = true;
          console.log('从IndexedDB加载了', areas.length, '个离线地图区域');
          
          // 如果在离线状态且有离线地图，自动切换到离线模式
          if (!isOnline.value && isMapOfflineAvailable.value) {
            showToast('已切换到离线地图模式');
          }
          return true;
        } else {
          // 如果IndexedDB中没有数据，尝试从localStorage迁移
          const savedAreas = localStorage.getItem('offlineMapAreas');
          if (savedAreas) {
            try {
              const legacyAreas = JSON.parse(savedAreas);
              offlineMapAreas.value = legacyAreas;
              isMapOfflineAvailable.value = legacyAreas.length > 0;
              
              // 将旧数据迁移到IndexedDB
              for (const area of legacyAreas) {
                await saveToStore(MAPS_STORE, area);
              }
              
              console.log('已将', legacyAreas.length, '个离线地图区域从localStorage迁移至IndexedDB');
              
              // 如果在离线状态且有离线地图，自动切换到离线模式
              if (!isOnline.value && isMapOfflineAvailable.value) {
                showToast('已切换到离线地图模式');
              } else if (!isOnline.value && !isMapOfflineAvailable.value) {
                showToast('无可用的离线地图，部分功能可能不可用');
              }
              
              return legacyAreas.length > 0;
            } catch (parseError) {
              console.error('解析离线地图数据失败:', parseError);
              offlineMapAreas.value = [];
              isMapOfflineAvailable.value = false;
              return false;
            }
          } else {
            // 无数据
            offlineMapAreas.value = [];
            isMapOfflineAvailable.value = false;
            
            if (!isOnline.value) {
              showToast('无可用的离线地图，部分功能可能不可用');
            }
            return false;
          }
        }
      } catch (error) {
        console.error('从IndexedDB检查离线地图失败:', error);
        
        // 出错时尝试从localStorage读取
        try {
          const savedAreas = localStorage.getItem('offlineMapAreas');
          if (savedAreas) {
            const areas = JSON.parse(savedAreas);
            offlineMapAreas.value = areas;
            isMapOfflineAvailable.value = areas.length > 0;
            
            if (!isOnline.value && isMapOfflineAvailable.value) {
              showToast('已切换到离线地图模式(本地缓存)');
            }
            return areas.length > 0;
          } else {
            offlineMapAreas.value = [];
            isMapOfflineAvailable.value = false;
            return false;
          }
        } catch (fallbackError) {
          console.error('回退到localStorage也失败:', fallbackError);
          offlineMapAreas.value = [];
          isMapOfflineAvailable.value = false;
          return false;
        }
      }
    };
    
    // 初始化离线地图实例
    const initOfflineMapInstance = async () => {
      console.log('正在初始化离线地图实例');
      showToast('正在加载离线地图...');
      
      // 创建一个简单的离线地图容器
      if (!mapContainer.value) {
        console.error('地图容器不存在');
        return;
      }
      
      try {
        // 检查是否有离线地图数据
        const hasOfflineMaps = await checkOfflineMaps();
        if (!hasOfflineMaps) {
          showToast('无可用的离线地图数据');
          return;
        }
        
        // 获取第一个离线地图区域作为初始显示
        const firstArea = offlineMapAreas.value[0];
        if (!firstArea || !firstArea.center) {
          showToast('离线地图数据不完整');
          return;
        }
        
        // 创建简单的离线地图
        const mapDiv = mapContainer.value;
        mapDiv.innerHTML = '';
        mapDiv.style.position = 'relative';
        mapDiv.style.backgroundColor = '#f0f0f0';
        
        // 创建离线提示
        const offlineNotice = document.createElement('div');
        offlineNotice.style.position = 'absolute';
        offlineNotice.style.top = '10px';
        offlineNotice.style.left = '10px';
        offlineNotice.style.backgroundColor = 'rgba(0,0,0,0.6)';
        offlineNotice.style.color = 'white';
        offlineNotice.style.padding = '5px 10px';
        offlineNotice.style.borderRadius = '4px';
        offlineNotice.style.zIndex = '1000';
        offlineNotice.textContent = '离线地图模式';
        mapDiv.appendChild(offlineNotice);
        
        // 尝试从缓存加载瓦片创建地图
        // 这里使用一个简单的实现，实际项目中可能需要更复杂的离线地图引擎
        
        // 设置初始位置为第一个离线区域的中心
        actualInitialPosition.value = firstArea.center;
        
        // 创建简单的标记点
        const markerElement = document.createElement('div');
        markerElement.className = 'offline-marker';
        markerElement.style.position = 'absolute';
        markerElement.style.top = '50%';
        markerElement.style.left = '50%';
        markerElement.style.width = '16px';
        markerElement.style.height = '16px';
        markerElement.style.borderRadius = '50%';
        markerElement.style.backgroundColor = '#1791fc';
        markerElement.style.border = '2px solid white';
        markerElement.style.transform = 'translate(-50%, -50%)';
        markerElement.style.zIndex = '100';
        mapDiv.appendChild(markerElement);
        
        // 设置地图状态
        map.value = {
          isOfflineMode: true,
          setCenter: () => {}, // 空函数，离线模式不支持
          remove: () => {}, // 空函数，离线模式不支持
          destroy: () => {
            mapDiv.innerHTML = '';
          },
          setFitView: () => {}, // 空函数，离线模式不支持
          setPitch: () => {}, // 空函数，离线模式不支持
          setRotation: () => {}, // 空函数，离线模式不支持
          setStatus: () => {}, // 空函数，离线模式不支持
          addControl: () => {}, // 空函数，离线模式不支持
          on: () => {} // 空函数，离线模式不支持
        };
        
        // 创建简单的标记对象
        marker.value = {
          setPosition: () => {} // 空函数，离线模式不支持
        };
        
        // 创建简单的轨迹线对象
        polyline.value = {
          getPath: () => [],
          setPath: () => {},
          setOptions: () => {}
        };
        
        // 创建简单的精度圆对象
        circle.value = {
          setCenter: () => {},
          setRadius: () => {},
          getRadius: () => 10
        };
        
        // 创建简单的定位对象
        geolocation.value = {
          getCurrentPosition: (callback: Function) => {
            // 使用离线区域中心作为当前位置
            if (actualInitialPosition.value) {
              callback('complete', {
                position: {
                  lng: actualInitialPosition.value[0],
                  lat: actualInitialPosition.value[1]
                },
                accuracy: 10
              });
            } else {
              callback('error', null);
            }
          },
          watchPosition: (options: any, callback: Function) => {
            // 使用离线区域中心作为当前位置
            if (actualInitialPosition.value) {
              callback('complete', {
                position: {
                  lng: actualInitialPosition.value[0],
                  lat: actualInitialPosition.value[1]
                },
                accuracy: 10
              });
            } else {
              callback('error', null);
            }
            return 0; // 返回一个假的watch ID
          },
          clearWatch: () => {}
        };
        
        showToast('离线地图已加载，部分功能可能受限');
      } catch (error) {
        console.error('初始化离线地图失败:', error);
        showToast('离线地图加载失败');
      }
    };
    
    // 不再需要IndexedDB，使用localStorage和Cache API代替
    
    // 初始化离线地图功能
    const initOfflineMapFeature = async () => {
      // 检查是否支持必要的API
      if (!('indexedDB' in window)) {
        console.error('您的浏览器不支持IndexedDB，离线地图功能将使用有限功能');
        if (!('localStorage' in window)) {
          console.error('您的浏览器也不支持localStorage，离线地图功能不可用');
          showToast('您的浏览器不支持离线存储，离线地图功能不可用');
          return;
        }
      }
      
      // 初始化数据库
      try {
        // 尝试打开数据库以验证其可用性
        await openDatabase();
        console.log('离线地图数据库初始化成功');
      } catch (dbError) {
        console.error('初始化离线地图数据库失败:', dbError);
        showToast('离线地图数据存储初始化失败，将使用有限功能');
      }
      
      if (!('serviceWorker' in navigator)) {
        console.error('您的浏览器不支持Service Worker，离线地图功能可能受限');
      } else {
        // 注册Service Worker，使用try/catch避免出错
        try {
          // 使用相对路径注册Service Worker，以适应各种部署环境
          // 注意：确保Service Worker文件存在于正确的位置
          let swPath;
          try {
            // 尝试使用相对于当前页面的路径
            swPath = new URL('./offline-map-worker.js', window.location.href).pathname;
          } catch (e) {
            // 回退到使用站点根目录
            swPath = '/offline-map-worker.js';
          }
          
          // 检查Service Worker文件是否存在
          fetch(swPath)
            .then(async response => {
              if (response.ok) {
                try {
                  // 注册Service Worker
                  const registration = await navigator.serviceWorker.register(swPath, {
                    scope: './' // 使用相对路径作为作用域
                  });
                  console.log('离线地图Service Worker注册成功:', registration.scope);
                  
                  // 等待Service Worker激活
                  if (registration.installing) {
                    registration.installing.addEventListener('statechange', event => {
                      if ((event.target as any).state === 'activated') {
                        console.log('Service Worker已激活');
                        initServiceWorker(registration);
                      }
                    });
                  } else if (registration.active) {
                    console.log('Service Worker已经处于激活状态');
                    initServiceWorker(registration);
                  }
                } catch (regError) {
                  console.error('注册Service Worker失败:', regError);
                }
              } else {
                console.warn('Service Worker文件不存在，跳过注册:', swPath);
              }
            })
            .catch(fetchError => {
              console.warn('无法检查Service Worker文件:', fetchError);
            });
        } catch (error) {
          console.error('离线地图Service Worker注册失败:', error);
        }
      }
      
      // 初始化Service Worker
      const initServiceWorker = (registration: ServiceWorkerRegistration) => {
        // 向Service Worker发送初始化消息
        if (registration.active) {
          // 添加消息监听，接收来自Service Worker的消息
          navigator.serviceWorker.addEventListener('message', event => {
            const data = event.data;
            if (data && data.type === 'CACHE_COMPLETE') {
              console.log('Service Worker缓存完成:', data.message);
              showToast('离线地图缓存已更新');
            } else if (data && data.type === 'CACHE_ERROR') {
              console.error('Service Worker缓存错误:', data.message);
            }
          });
          
          // 发送初始化消息
          registration.active.postMessage({
            type: 'INIT_DB',
            dbName: DB_NAME,
            version: DB_VERSION,
            stores: [RECORDS_STORE, MAPS_STORE, MAP_TILES_STORE]
          });
          
          // 预缓存关键资源
          registration.active.postMessage({
            type: 'PRECACHE_RESOURCES',
            resources: [
              './',
              './index.html',
              './favicon.ico'
            ]
          });
        }
      };
      
      // 检查离线地图
      try {
        await checkOfflineMaps();
      } catch (error) {
        console.error('离线地图初始化失败:', error);
      }
    };
    
    // 显示离线地图管理面板
    const showOfflineMapManager = () => {
      showOfflineMapPanel.value = true;
    };
    
    // 关闭离线地图管理面板
    const closeOfflineMapManager = () => {
      showOfflineMapPanel.value = false;
    };
    
    // 将经纬度范围转换为瓦片坐标
    const latLngToTile = (lat: number, lng: number, zoom: number): [number, number] => {
      const n = Math.pow(2, zoom);
      const xtile = Math.floor((lng + 180) / 360 * n);
      const ytile = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * n);
      return [xtile, ytile];
    };
    
    // 计算区域内的瓦片范围
    const calculateTileRange = (center: [number, number], radius: number, zoom: number): Array<{ x: number, y: number, z: number }> => {
      const [centerLng, centerLat] = center;
      
      // 计算边界点坐标（粗略估算）
      const earthRadius = 6378137; // 地球半径（米）
      const latDiff = (radius / earthRadius) * (180 / Math.PI);
      const lngDiff = (radius / earthRadius) * (180 / Math.PI) / Math.cos(centerLat * Math.PI / 180);
      
      const north = centerLat + latDiff;
      const south = centerLat - latDiff;
      const east = centerLng + lngDiff;
      const west = centerLng - lngDiff;
      
      // 转换为瓦片坐标
      const [minTileX, minTileY] = latLngToTile(north, west, zoom);
      const [maxTileX, maxTileY] = latLngToTile(south, east, zoom);
      
      // 生成瓦片列表
      const tiles = [];
      for (let x = minTileX; x <= maxTileX; x++) {
        for (let y = minTileY; y <= maxTileY; y++) {
          tiles.push({ x, y, z: zoom });
        }
      }
      
      return tiles;
    };
    
    // 下载当前位置周边地图
    const downloadCurrentArea = async () => {
      if (!actualInitialPosition.value) {
        showToast('请等待定位完成后再下载离线地图');
        return;
      }
      
      if (isDownloadingMap.value) {
        showToast('正在下载中，请稍后再试');
        return;
      }
      
      // 开始下载指定半径范围的离线地图
      // 确保centerPosition是一个简单的数组，而不是复杂对象
      const centerPosition: [number, number] = [
        actualInitialPosition.value[0], 
        actualInitialPosition.value[1]
      ];
      const areaName = `附近${(selectedRadius.value/1000).toFixed(1)}公里`;
      
      try {
        await downloadMapArea(areaName, centerPosition, selectedRadius.value);
      } catch (error) {
        console.error('下载离线地图失败:', error);
        showToast('下载离线地图失败，请重试');
      }
    };
    
    // 下载并存储地图区域
    const downloadMapArea = async (name: string, center: [number, number], radius: number) => {
      if (!window.AMap || !map.value) {
        showToast('地图未初始化，无法下载离线地图');
        return;
      }
      
      if (isDownloadingMap.value) {
        showToast('正在下载另一个区域，请稍后再试');
        return;
      }
      
      try {
        isDownloadingMap.value = true;
        downloadProgress.value = 0;
        
        // 我们不再使用IndexedDB存储瓦片数据，仅使用localStorage存储区域信息
        // 这样可以避免复杂的数据库操作和可能的克隆错误
        
        // 创建区域信息
        const areaId = `area_${Date.now()}`;
        
        // 确保center是简单的数值数组，可被正确克隆
        let centerArray: [number, number] = [0, 0]; 
        
        if (Array.isArray(center)) {
          // 如果是数组，直接转换为数字数组
          centerArray = [Number(center[0]), Number(center[1])];
        } else if (typeof center === 'object' && center !== null) {
          // 处理可能是LngLat对象的情况
          const centerObj = center as any;
          if ('lng' in centerObj && 'lat' in centerObj) {
            centerArray = [Number(centerObj.lng), Number(centerObj.lat)];
          }
        }
            
        const areaInfo = {
          id: areaId,
          name: name || `附近${(radius/1000).toFixed(1)}公里`,
          center: centerArray,
          radius: Number(radius),
          size: '计算中...',
          date: new Date().toISOString()
        };
        
        showToast(`开始下载离线地图: ${areaInfo.name}`);
        
        // 计算需要下载的瓦片
        // 根据半径选择合适的缩放级别，避免下载过多瓦片
        let zoomLevels: number[] = [];
        if (radius <= 2000) { // 2km内，提供更高精度
          zoomLevels = [13, 14, 15, 16];
        } else if (radius <= 5000) { // 5km内
          zoomLevels = [12, 13, 14, 15];
        } else if (radius <= 10000) { // 10km内
          zoomLevels = [11, 12, 13, 14];
        } else { // 10km以上
          zoomLevels = [10, 11, 12, 13];
        }
        
        let allTiles: Array<{ x: number, y: number, z: number }> = [];
        
        // 最大瓦片限制，防止下载过多导致存储问题
        const MAX_TILES = 2000;
        
        // 根据缩放级别计算瓦片
        for (const zoom of zoomLevels) {
          const tiles = calculateTileRange(center, radius, zoom);
          allTiles = allTiles.concat(tiles);
          
          // 如果超过限制，提前中断并警告
          if (allTiles.length > MAX_TILES) {
            allTiles = allTiles.slice(0, MAX_TILES);
            showToast(`瓦片数量过多，已限制为${MAX_TILES}个。可能会影响部分区域显示。`);
            break;
          }
        }
        
        // 计算预估大小（每个瓦片约10KB）
        const estimatedSize = (allTiles.length * 10) / 1024;
        areaInfo.size = `${estimatedSize.toFixed(1)}MB`;
        
        // 保存区域信息到IndexedDB
        try {
          // 保存区域信息到IndexedDB
          await saveToStore(MAPS_STORE, areaInfo);
          console.log('成功保存离线地图区域信息到IndexedDB:', areaInfo.id);
          
          // 同时作为备份保存到localStorage
          try {
            // 获取现有离线地图区域列表
            let areas = [];
            const savedAreas = localStorage.getItem('offlineMapAreas');
            if (savedAreas) {
              areas = JSON.parse(savedAreas);
            }
            
            // 添加新区域
            areas.push(areaInfo);
            
            // 保存回localStorage作为备份
            localStorage.setItem('offlineMapAreas', JSON.stringify(areas));
          } catch (localError) {
            console.warn('备份离线地图区域信息到localStorage失败:', localError);
          }
        } catch (storageError) {
          console.error('保存区域信息到IndexedDB失败:', storageError);
          
          // 尝试回退到localStorage
          try {
            // 获取现有离线地图区域列表
            let areas = [];
            const savedAreas = localStorage.getItem('offlineMapAreas');
            if (savedAreas) {
              areas = JSON.parse(savedAreas);
            }
            
            // 添加新区域
            areas.push(areaInfo);
            
            // 保存回localStorage
            localStorage.setItem('offlineMapAreas', JSON.stringify(areas));
          } catch (e) {
            console.error('回退到localStorage也失败:', e);
            showToast('保存地图信息失败，但下载仍将继续');
          }
        }
        
        // 开始下载瓦片
        let downloaded = 0;
        const batchSize = 5; // 减小批量下载数量，降低并发压力
        
        const downloadTileBatch = async (startIdx: number) => {
          const batch = allTiles.slice(startIdx, startIdx + batchSize);
          
          if (batch.length === 0) {
            // 下载完成
            isDownloadingMap.value = false;
            downloadProgress.value = 100;
            
            // 更新离线地图列表
            checkOfflineMaps();
            showToast(`离线地图下载完成: ${areaInfo.name}`);
            return;
          }
          
          // 顺序下载瓦片
          for (const tile of batch) {
            try {
              // 构建瓦片URL（高德地图的瓦片URL格式）
              const serverNum = Math.floor(Math.random() * 4) + 1;
              const url = `https://webrd0${serverNum}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x=${tile.x}&y=${tile.y}&z=${tile.z}`;
              
              // 获取瓦片数据
              const response = await fetch(url);
              
              // 同时将瓦片保存到IndexedDB和缓存
              try {
                // 1. 保存到Cache API
                if ('caches' in window) {
                  const cache = await caches.open('offline-map-tiles');
                  await cache.put(url, response.clone());
                }
                
                // 2. 保存到IndexedDB
                try {
                  // 从响应中获取arrayBuffer数据(比Blob更适合IndexedDB)
                  const buffer = await response.clone().arrayBuffer();
                  
                  // 创建瓦片数据对象
                  const tileData = {
                    url: url,                    // 瓦片URL作为键
                    areaId: String(areaId),      // 确保areaId是字符串
                    x: tile.x,                   // 瓦片x坐标
                    y: tile.y,                   // 瓦片y坐标
                    z: tile.z,                   // 缩放级别
                    data: buffer,                // 瓦片二进制数据
                    timestamp: Date.now()        // 保存时间戳
                  };
                  
                  // 保存到IndexedDB
                  await saveToStore(MAP_TILES_STORE, tileData);
                } catch (dbError) {
                  console.warn('保存瓦片到IndexedDB失败，将仅使用缓存:', dbError);
                  // 继续流程，不中断下载
                }
                
                // 更新进度
                downloaded++;
                downloadProgress.value = Math.floor((downloaded / allTiles.length) * 100);
              } catch (cacheError) {
                console.error('保存瓦片失败:', cacheError);
              }
            } catch (error) {
              console.error('下载瓦片失败:', error);
            }
          }
          
          // 处理下一批次
          await downloadTileBatch(startIdx + batchSize);
        };
        
        // 开始下载第一批次
        await downloadTileBatch(0);
        
      } catch (error) {
        console.error('下载离线地图失败:', error);
        showToast('下载离线地图失败，请重试');
        isDownloadingMap.value = false;
      }
    };
    
    // 删除离线地图区域
    const deleteOfflineMapArea = async (areaId: string) => {
      try {
        // 从IndexedDB中删除区域信息
        await deleteFromStore(MAPS_STORE, areaId);
        
        // 删除所有相关的瓦片数据
        await deleteTilesByAreaId(areaId);
        
        // 尝试清除相关缓存
        if ('caches' in window) {
          try {
            // 发送消息给Service Worker，告知区域已删除
            if (navigator.serviceWorker && navigator.serviceWorker.controller) {
              navigator.serviceWorker.controller.postMessage({
                type: 'AREA_DELETED',
                areaId: areaId
              });
            }
          } catch (cacheError) {
            console.error('清除缓存失败:', cacheError);
          }
        }
        
        // 同步更新localStorage中的区域信息（作为备份）
        try {
          // 过滤掉被删除的区域
          const updatedAreas = offlineMapAreas.value.filter(area => area.id !== areaId);
          localStorage.setItem('offlineMapAreas', JSON.stringify(updatedAreas));
        } catch (localError) {
          console.warn('更新localStorage备份失败:', localError);
        }
        
        // 更新列表
        await checkOfflineMaps();
        showToast('离线地图已删除');
      } catch (error) {
        console.error('从IndexedDB删除离线地图失败:', error);
        showToast('删除离线地图失败，请稍后再试');
        
        // 回退到尝试从localStorage删除
        try {
          const savedAreas = localStorage.getItem('offlineMapAreas');
          if (savedAreas) {
            let areas = JSON.parse(savedAreas);
            areas = areas.filter((area: any) => area.id !== areaId);
            localStorage.setItem('offlineMapAreas', JSON.stringify(areas));
            
            // 重新加载区域列表
            await checkOfflineMaps();
            showToast('离线地图已删除（使用备份存储）');
          }
        } catch (fallbackError) {
          console.error('回退删除也失败:', fallbackError);
        }
      }
    };

          return {
      distance,
      calories,
      duration,
      currentSpeed,
      isRunning,
      showSummary,
      isPanelExpanded,
      avgPace,
      paceFormatted,
      mapContainer,
      formatTime,
      startTracking,
      stopTracking,
      saveSummary,
      shareSummary,
      closeSummary,
      goBack,
      expandPanel,
      collapsePanel,
      startDrag,
      onDrag,
      endDrag,
      currentSong,
      isPlaying,
      togglePlay,
      playPrevious,
      playNext,
      toggleAutoPause,
      elevationData,
      currentElevation,
      totalAscent,
      totalDescent,
      elevationChartPoints,
      autoPauseEnabled,
      isAutoPaused,
      gpsSignalStatus,
      gpsStatusText,
      showingToast,
      toastMessage,
      viewRunHistory,
      closeHistory,
      showHistory,
      savedRecords,
      selectedRecord,
      viewRecordDetail,
      closeRecordDetail,
      deleteRecord,
      getElevationChartPoints,
      detailMapContainer,
      // 语音控制相关
      isListening,
      voiceFeedback,
      toggleVoiceFeedback,
      // AI教练相关
      aiCoachEnabled,
      toggleAICoach,
      effortLevel,
      paceStability,
      // 目标跑相关
      isTargetRunMode,
      searchKeyword,
      nearbyPOIs,
      completionRate,
      switchToFreeRun,
      switchToTargetRun,
      searchDestination,
      selectDestination,
      showDestinationPanel,
      targetRoute,
      // 离线地图相关
      isOnline,
      isMapOfflineAvailable,
      offlineMapAreas,
      isDownloadingMap,
      downloadProgress,
      showOfflineMapPanel,
      showOfflineMapManager,
      closeOfflineMapManager,
      downloadCurrentArea,
      deleteOfflineMapArea,
      selectedRadius,
      // 添加AI推荐生成函数到导出
      generateAIRecommendations
    };
  }
});
</script>

<style scoped>
.free-running {
  position: relative;
  height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: #f5f5f5;
}

.map-container {
  flex: 1;
  width: 100%;
  position: relative;
}

.back-button {
  position: absolute;
  top: 15px;
  left: 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 8px 15px;
  border-radius: 20px;
  z-index: 101; /* 增加z-index确保在最上层 */
  display: flex;
  align-items: center;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.back-button span {
  margin-left: 5px;
  font-size: 14px;
}

/* 重新选择目的地按钮 */
.reselect-button {
  position: absolute;
  top: 70px;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 8px 15px;
  border-radius: 20px;
  z-index: 101;
  display: flex;
  align-items: center;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.reselect-button svg {
  margin-right: 5px;
}

.reselect-button span {
  font-size: 14px;
}

/* 迷你音乐播放器 */
.mini-music-player {
  position: absolute;
  bottom: 80px;
  left: 50%;
  transform: translateX(-50%);
  width: 90%;
  max-width: 350px;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 12px;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  z-index: 5;
}

.mini-music-player .album-cover {
  width: 36px;
  height: 36px;
  border-radius: 4px;
  overflow: hidden;
}

.mini-music-player .music-info {
  flex: 1;
  padding: 0 10px;
}

.mini-music-player .song-title {
  color: white;
  font-size: 14px;
}

.mini-music-player .artist-name {
  color: rgba(255, 255, 255, 0.7);
  font-size: 12px;
}

/* 可滑动面板 */
.sliding-panel {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #fff;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease;
  transform: translateY(calc(100% - 220px));
  z-index: 10;
  height: 70vh;
  max-height: 600px;
  display: flex;
  flex-direction: column;
}

.sliding-panel.expanded {
  transform: translateY(0);
}

.panel-header {
  padding: 10px 15px;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.95);
  border-radius: 20px 20px 0 0;
  touch-action: none; /* 防止滑动手势冲突 */
}

.handle-bar {
  width: 40px;
  height: 4px;
  background-color: #ddd;
  border-radius: 2px;
  margin-bottom: 6px;
}

.workout-title {
  display: flex;
  align-items: center;
  margin-top: 5px;
  font-size: 16px;
  font-weight: 500;
}

.workout-title svg {
  margin-right: 5px;
}

/* 收起状态的小面板 */
.mini-stats {
  padding: 5px 15px 15px;
}

.big-stat {
  background-color: #f0f8ff;
  border-radius: 12px;
  padding: 15px;
  text-align: center;
  margin-bottom: 15px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.big-stat-value {
  font-size: 40px;
  font-weight: bold;
  color: #333;
  line-height: 1;
  position: relative;
}

.big-stat-unit {
  font-size: 16px;
  font-weight: normal;
  position: absolute;
  right: -25px;
  bottom: 5px;
}

.big-stat-label {
  font-size: 14px;
  color: #666;
  margin-top: 5px;
}

.mini-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 10px;
}

.mini-stat-box {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 12px;
  text-align: center;
}

.mini-stat-value {
  font-size: 22px;
  font-weight: bold;
  color: #333;
}

.mini-stat-label {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

/* 展开状态的详细面板 */
.panel-content {
  padding: 15px;
  flex: 1;
  overflow-y: auto;
}

.stats-container {
  margin-bottom: 15px;
}

.stat-box {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 15px;
  text-align: center;
  margin-bottom: 10px;
}

.stat-box.distance {
  background-color: #f0f8ff;
}

.stats-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.stats-row .stat-box {
  flex: 1;
  margin-bottom: 0;
}

.stat-big-value {
  font-size: 40px;
  font-weight: bold;
  color: #333;
  line-height: 1.2;
  position: relative;
  display: inline-block;
}

.stat-value {
  font-size: 24px;
  font-weight: bold;
  color: #333;
}

.unit {
  font-size: 16px;
  font-weight: normal;
  margin-left: 2px;
}

.stat-label {
  font-size: 14px;
  color: #666;
  margin-top: 5px;
}

.panel-footer {
  padding: 15px;
  border-top: 1px solid #f0f0f0;
}

/* 音乐播放器内嵌组件 */
.music-player-embedded {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 12px;
  display: flex;
  align-items: center;
  margin-top: 15px;
}

.album-cover {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  overflow: hidden;
  margin-right: 10px;
}

.album-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.music-info {
  flex: 1;
  overflow: hidden;
}

.song-title {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.artist-name {
  font-size: 12px;
  color: #666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.player-controls {
  display: flex;
  align-items: center;
}

.control-button {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 5px;
}

.control-button.play {
  width: 36px;
  height: 36px;
}

/* 按钮样式 */
.action-button {
  width: 100%;
  padding: 12px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.start-button {
  background-color: #07c160;
  color: white;
}

.stop-button {
  background-color: #f5222d;
  color: white;
}

.action-button:active {
  transform: scale(0.98);
  opacity: 0.9;
}

/* 自定义定位标记样式 */
:deep(.location-marker) {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(7,193,96,1) 0%, rgba(7,193,96,1) 30%, rgba(7,193,96,0) 70%);
  box-shadow: 0 0 0 2px white, 0 0 5px 1px rgba(0, 0, 0, 0.3);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(7, 193, 96, 0.7), 0 0 0 2px white;
  }
  70% {
    box-shadow: 0 0 0 10px rgba(7, 193, 96, 0), 0 0 0 2px white;
  }
  100% {
    box-shadow: 0 0 0 0 rgba(7, 193, 96, 0), 0 0 0 2px white;
  }
}

/* 结束跑步总结弹窗 */
.summary-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

.summary-content {
  width: 90%;
  max-width: 400px;
  background-color: white;
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  animation: slideUp 0.3s ease;
}

.summary-content h2 {
  text-align: center;
  margin-bottom: 20px;
  color: #333;
  font-size: 20px;
}

.summary-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.summary-item {
  text-align: center;
  padding: 10px;
  background-color: #f5f5f5;
  border-radius: 8px;
}

.summary-value {
  font-size: 20px;
  font-weight: bold;
  color: #333;
  margin-bottom: 4px;
}

.summary-label {
  font-size: 12px;
  color: #666;
}

.summary-actions {
  display: flex;
  gap: 12px;
}

.summary-button {
  flex: 1;
  padding: 12px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.save-button {
  background-color: #07c160;
  color: white;
}

.share-button {
  width: 48px;
  flex: 0;
  background-color: #1890ff;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideUp {
  from { transform: translateY(50px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* 适配安全区域 */
@supports (padding-bottom: env(safe-area-inset-bottom)) {
  .sliding-panel {
    padding-bottom: env(safe-area-inset-bottom);
  }
  
  .panel-footer {
    padding-bottom: calc(15px + env(safe-area-inset-bottom));
  }
}

/* 暗黑模式支持 */
@media (prefers-color-scheme: dark) {
  .sliding-panel,
  .panel-header {
    background-color: rgba(30, 30, 30, 0.95);
  }
  
  .handle-bar {
    background-color: #444;
  }
  
  .mini-stat-value,
  .big-stat-value,
  .stat-value,
  .stat-big-value {
    color: #fff;
  }
  
  .mini-stat-label,
  .big-stat-label,
  .stat-label,
  .artist-name {
    color: #aaa;
  }
  
  .panel-header {
    border-bottom: 1px solid #333;
  }
  
  .panel-footer {
    border-top: 1px solid #333;
  }
  
  .stat-box,
  .mini-stat-box {
    background-color: #2a2a2a;
  }
  
  .stat-box.distance,
  .big-stat {
    background-color: #1a2a3a;
  }
  
  .music-player-embedded {
    background-color: #2a2a2a;
  }
  
  .workout-title {
    color: #fff;
  }
  
  .song-title {
    color: #fff;
  }
  
  .summary-content {
    background-color: #222;
  }
  
  .summary-content h2 {
    color: #fff;
  }
  
  .summary-item {
    background-color: #333;
  }
  
  .summary-value {
    color: #fff;
  }
  
  .summary-label {
    color: #aaa;
  }
}

/* 状态指示器 */
.status-indicators {
  position: absolute;
  top: 15px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  z-index: 100;
}

.status-indicator {
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 5px 10px;
  border-radius: 15px;
  display: flex;
  align-items: center;
  font-size: 12px;
}

.status-indicator svg {
  margin-right: 5px;
}

.status-indicator.strong {
  background-color: rgba(7, 193, 96, 0.7);
}

.status-indicator.weak {
  background-color: rgba(255, 193, 7, 0.7);
}

.status-indicator.lost {
  background-color: rgba(244, 67, 54, 0.7);
}

/* Toast提示 */
.toast-message {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px 20px;
  border-radius: 8px;
  z-index: 1000;
  font-size: 14px;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

/* 历史记录按钮 */
.history-button {
  position: absolute;
  top: 135px; /* 调整到罗盘下方 */
  right: 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 101; /* 增加z-index确保在最上层 */
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.history-button:active {
  transform: scale(0.95);
}

/* 历史记录弹窗 */
.history-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

.history-content {
  width: 90%;
  max-width: 500px;
  height: 80%;
  max-height: 600px;
  background-color: white;
  border-radius: 16px;
  padding: 16px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
  margin-bottom: 10px;
}

.history-header h2 {
  margin: 0;
  font-size: 20px;
}

.close-button {
  cursor: pointer;
  padding: 5px;
  background-color: #f5f5f5;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  transition: all 0.2s ease;
}

.close-button:hover {
  background-color: #e0e0e0;
  transform: scale(1.1);
}

.close-button svg {
  display: block;
}

.close-button svg path {
  fill: #666 !important;
}

.history-list {
  flex: 1;
  overflow-y: auto;
  padding-right: 5px;
}

.history-item {
  background-color: #f8f8f8;
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: transform 0.2s;
}

.history-item:active {
  transform: scale(0.98);
}

.history-item-date {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 8px;
}

.history-item-stats {
  display: flex;
  justify-content: space-between;
}

.history-stat {
  text-align: center;
}

.history-stat .stat-value {
  font-size: 16px;
  font-weight: bold;
}

.history-stat .stat-label {
  font-size: 12px;
  color: #666;
  margin-top: 2px;
}

.empty-history {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #999;
}

.empty-icon {
  margin-bottom: 10px;
}

.empty-text {
  font-size: 16px;
}

/* 记录详情弹窗 */
.record-detail-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: white;
  z-index: 1010;
  animation: slideUp 0.3s ease;
  display: flex;
  flex-direction: column;
}

.record-detail-content {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}

.record-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.record-detail-header .back-button {
  position: static;
  background: none;
  color: #333;
  display: flex;
  align-items: center;
}

.delete-button {
  padding: 8px;
  cursor: pointer;
}

.record-detail-date {
  margin-bottom: 15px;
  font-size: 16px;
  color: #666;
}

.record-detail-stats {
  margin-bottom: 20px;
}

.detail-stat-box {
  background-color: #f0f8ff;
  border-radius: 12px;
  padding: 15px;
  text-align: center;
  margin-bottom: 15px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.detail-stat-value {
  font-size: 40px;
  font-weight: bold;
  color: #333;
  line-height: 1;
  position: relative;
}

.detail-stat-unit {
  font-size: 16px;
  font-weight: normal;
  position: absolute;
  right: -25px;
  bottom: 5px;
}

.detail-stat-label {
  font-size: 14px;
  color: #666;
  margin-top: 5px;
}

.detail-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-gap: 10px;
}

.detail-mini-stat {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 12px;
  text-align: center;
}

.detail-mini-value {
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

.detail-mini-label {
  font-size: 12px;
  color: #666;
  margin-top: 5px;
}

.track-preview-container {
  margin: 15px 0;
  border-radius: 12px;
  overflow: hidden;
  height: 250px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.detail-map-container {
  width: 100%;
  height: 100%;
}

.detail-elevation-chart,
.detail-ai-coach {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 15px;
  margin-bottom: 15px;
}

.detail-elevation-chart .chart-header,
.detail-ai-coach .chart-header {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
}

.detail-ai-analysis {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 15px;
  margin-top: 15px;
}

.analysis-header {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
}

.analysis-content {
  display: flex;
  justify-content: space-around;
}

.analysis-item {
  text-align: center;
}

.analysis-label {
  font-size: 12px;
  color: #666;
  margin-bottom: 5px;
}

.analysis-value {
  font-size: 16px;
  font-weight: bold;
}

/* 海拔图表 */
.elevation-chart {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 15px;
  margin-top: 15px;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.elevation-stats {
  font-size: 14px;
}

.elevation-stats .stat {
  margin-left: 10px;
}

.chart-container {
  position: relative;
}

.elevation-summary {
  background-color: #f8f8f8;
  border-radius: 12px;
  padding: 15px;
  margin: 15px 0;
}

.elevation-summary h3 {
  margin: 0 0 10px 0;
  font-size: 16px;
}

/* 功能按钮区 */
.panel-tools {
  display: flex;
  justify-content: space-around;
  margin-bottom: 10px;
}

.tool-button {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: none;
  border: none;
  padding: 5px 10px;
  cursor: pointer;
}

.tool-button span {
  font-size: 12px;
  margin-top: 5px;
  color: #666;
}

/* 暗黑模式支持 */
@media (prefers-color-scheme: dark) {
  /* ... existing dark mode styles ... */

  .history-content,
  .record-detail-modal {
    background-color: #222;
  }

  .history-header {
    border-bottom-color: #333;
  }

  .history-header h2,
  .detail-stat-value,
  .detail-mini-value,
  .record-detail-header .back-button {
    color: #fff;
  }

  .history-item {
    background-color: #333;
  }

  .history-stat .stat-label,
  .detail-stat-label,
  .detail-mini-label,
  .record-detail-date,
  .tool-button span {
    color: #aaa;
  }

  .close-button path,
  .record-detail-header .back-button path {
    fill: #fff;
  }

  .detail-stat-box {
    background-color: #1a2a3a;
  }

  .detail-mini-stat,
  .detail-elevation-chart,
  .elevation-chart,
  .elevation-summary {
    background-color: #333;
  }
}

/* 语音控制状态指示器 */
.voice-indicator {
  position: absolute;
  bottom: 80px;
  right: 15px;
  background-color: rgba(7, 193, 96, 0.8);
  color: white;
  padding: 5px 10px;
  border-radius: 20px;
  display: flex;
  align-items: center;
  font-size: 12px;
  z-index: 100;
  animation: pulse-green 1.5s infinite;
}

.voice-indicator svg {
  margin-right: 5px;
}

@keyframes pulse-green {
  0% {
    box-shadow: 0 0 0 0 rgba(7, 193, 96, 0.7);
  }
  70% {
    box-shadow: 0 0 0 10px rgba(7, 193, 96, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(7, 193, 96, 0);
  }
}

/* 功能按钮区 */
.panel-tools {
  display: flex;
  justify-content: space-around;
  margin-bottom: 10px;
}

/* 目标跑模式相关样式 */
.run-mode-selector {
  position: absolute;
  top: 70px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 22px;
  overflow: hidden;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  width: auto;
}

.run-mode-selector button {
  padding: 12px 22px;
  border: none;
  background: transparent;
  color: white;
  font-size: 16px;
  font-weight: 500;
  outline: none;
  min-width: 90px;
  transition: all 0.3s ease;
}

.run-mode-selector button.active {
  background: #07c160;
  box-shadow: 0 0 10px rgba(7, 193, 96, 0.5) inset;
  font-weight: 600;
}

.destination-panel {
  position: absolute;
  top: 130px; /* 调整位置避免与模式切换按钮重叠 */
  left: 15px;
  right: 15px;
  background: white;
  border-radius: 16px;
  padding: 20px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 99; /* 低于按钮z-index */
  max-height: 45%;
  overflow-y: auto;
}

.panel-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
  text-align: center;
}

.search-container {
  display: flex;
  margin-bottom: 15px;
  position: relative;
}

.search-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
}

.search-container input {
  flex: 1;
  padding: 8px 12px 8px 35px;
  border: 1px solid #ddd;
  border-radius: 4px 0 0 4px;
  font-size: 14px;
}

.search-btn {
  padding: 8px 15px;
  background: #07c160;
  color: white;
  border: none;
  border-radius: 0 4px 4px 0;
  font-size: 14px;
}

.destination-list {
  max-height: 300px;
  overflow-y: auto;
}

.destination-item {
  padding: 10px;
  border-bottom: 1px solid #eee;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.poi-info {
  flex: 1;
}

.poi-name {
  font-weight: 500;
  margin-bottom: 5px;
}

.poi-distance {
  font-size: 12px;
  color: #666;
}

.select-btn {
  background: #f0f0f0;
  color: #333;
  padding: 5px 10px;
  border-radius: 15px;
  font-size: 12px;
}

/* 网络状态指示器 */
.network-status {
  position: absolute;
  top: 70px;
  left: 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 5px 10px;
  border-radius: 15px;
  display: flex;
  align-items: center;
  font-size: 12px;
  z-index: 100;
}

.network-status svg {
  margin-right: 5px;
}

/* 离线地图入口按钮 */
.offline-map-button {
  position: absolute;
  top: 195px;  /* 调整到历史按钮下方 */
  right: 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 101; /* 增加z-index确保在最上层 */
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.offline-map-button:active {
  transform: scale(0.95);
}

/* 离线地图管理面板 */
.offline-map-panel {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

.offline-panel-content {
  width: 90%;
  max-width: 400px;
  background-color: white;
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  animation: slideUp 0.3s ease;
}

.offline-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  border-bottom: 1px solid #eee;
}

.offline-panel-header h2 {
  margin: 0;
  font-size: 20px;
}

.close-button {
  cursor: pointer;
  padding: 5px;
}

.download-section {
  margin-bottom: 20px;
}

.section-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
}

.radius-selector {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.radius-label {
  margin-right: 10px;
  font-size: 14px;
}

.radius-options {
  display: flex;
  gap: 10px;
}

.radius-options button {
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  background-color: #f0f0f0;
  color: #333;
  cursor: pointer;
  transition: background-color 0.2s;
}

.radius-options button.active {
  background-color: #07c160;
  color: white;
}

.download-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.download-button {
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  background-color: #07c160;
  color: white;
  cursor: pointer;
  transition: background-color 0.2s;
}

.download-button:hover {
  background-color: #05a150;
}

.progress-bar {
  width: 100%;
  height: 10px;
  background-color: #f0f0f0;
  border-radius: 5px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background-color: #07c160;
  transition: width 0.3s ease;
}

.offline-maps-list {
  margin-bottom: 20px;
}

.map-items {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.map-item {
  background-color: #f8f8f8;
  border-radius: 8px;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.map-info {
  flex: 1;
}

.map-name {
  font-size: 14px;
  font-weight: 500;
}

.map-details {
  font-size: 12px;
  color: #666;
}

.delete-map-btn {
  padding: 5px;
  cursor: pointer;
}

.offline-note {
  font-size: 12px;
  color: #666;
}

/* AI教练状态面板 */
.ai-coach-panel {
  margin-top: 15px;
  padding: 15px;
  background-color: #f8f8f8;
  border-radius: 12px;
}

.coach-status {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 10px;
}

.coach-status.active {
  color: #07c160;
}

.coach-status.inactive {
  color: #999;
}

.coach-metrics {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.metric-box {
  text-align: center;
}

.metric-label {
  font-size: 14px;
  color: #666;
  margin-bottom: 5px;
}

.metric-value {
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

.effort-indicator {
  font-size: 16px;
  margin-bottom: 5px;
}

.effort-level {
  font-weight: 500;
}

.effort-level.easy {
  color: #4CAF50;
}

.effort-level.moderate {
  color: #FFC107;
}

.effort-level.hard {
  color: #F44336;
}

.effort-level.max {
  color: #9C27B0;
}

.stability-bar {
  width: 100%;
  height: 10px;
  background-color: #f0f0f0;
  border-radius: 5px;
  overflow: hidden;
}

.stability-fill {
  height: 100%;
  transition: width 0.3s ease;
}

.stability-fill.good {
  background-color: #4CAF50;
}

.stability-fill.normal {
  background-color: #FFC107;
}

.stability-fill.poor {
  background-color: #F44336;
}

.stability-value {
  font-size: 12px;
  color: #666;
  margin-top: 5px;
}

.disabled-message {
  font-size: 14px;
  color: #999;
  text-align: center;
}

/* AI教练建议 */
.ai-coach-summary {
  margin-top: 15px;
  padding: 15px;
  background-color: #f8f8f8;
  border-radius: 12px;
}

.coach-recommendations {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.recommendation-item {
  display: flex;
  align-items: center;
}

.recommendation-bullet {
  font-size: 16px;
  margin-right: 5px;
}

.recommendation-text {
  font-size: 14px;
  color: #666;
}
</style>